简体   繁体   English

是否应该在赋值时调用构造函数?

[英]Should a constructor ever be called on assignment?

The output of the code below in VS2015 is "constructor". VS2015中以下代码的输出是“构造函数”。

Shouldn't it fail to compile due to the missing assignment operator? 由于缺少赋值运算符,它不应该无法编译吗?

struct A { };

struct B {
    B(){}
    B(const A& a) {
        cout << "constructor" << endl;
    }

    //B& operator=(const A& a) {
    //  cout << "assignment operator" << endl;
    //  return *this;
    //}
};

int main() {
    A a;
    B b;
    b = a;

    return 0;
}

Yes, when there is a conversion going on, like in your testcase. 是的,当有转换时,就像在您的测试用例中一样。

You're effectively calling 你有效地打电话了

b = B(a);

Because B 's assignment operator B& operator=(B const&) is implicitly declared, it is found during overload resolution. 因为B的赋值运算符B& operator=(B const&)是隐式声明的,所以在重载解析期间会找到它。 Because your assignment is only one conversion away from being a match (and that's exactly the number of conversions that are allowed to happen), it converts a to B and then assigns the new temporary B to b . 因为您的分配只是一次转换而不是匹配(并且这恰好是允许发生的转换次数),所以它将a转换为B ,然后将新的临时B分配给b

Let's consider an analogous example. 让我们考虑一个类似的例子。

double a;
int b=5;

a=b;

The only thing you can assign to a double is another double . 你可以分配给double的唯一的东西是另一个double However, an int can be converted to a double . 但是, int可以转换为double

Similarly here, A can be converted to B , because the constructor to do so exists. 同样在这里, A可以转换为B ,因为存在这样的构造函数。 And that's what happens. 这就是发生的事情。

Your code has implicit conversion from A to B , the b = a is compiled as b = B(a); 你的代码有从AB隐式转换, b = a编译为b = B(a); . If you want this to be detected as error, you can use the explicit specifier : 如果要将其检测为错误,可以使用explicit说明符

struct B {
    B(){}
    explicit B(const A& a) {
        std::cout << "constructor" << std::endl;
    }
};

Then you should get error, such as these generated by ideone.com : 然后你应该得到错误,例如ideone.com生成的错误

prog.cpp: In function 'int main()':
prog.cpp:20:7: error: no match for 'operator=' (operand types are 'B' and 'A')
     b = a;
       ^
prog.cpp:5:8: note: candidate: B& B::operator=(const B&)
 struct B {
        ^
prog.cpp:5:8: note:   no known conversion for argument 1 from 'A' to 'const B&'
prog.cpp:5:8: note: candidate: B& B::operator=(B&&)
prog.cpp:5:8: note:   no known conversion for argument 1 from 'A' to 'B&&'

After that, the constructor will never be implicitly called, and if you want to call it, you have to write it explicitly: b = B(a); 之后,永远不会隐式调用构造函数,如果要调用它,则必须明确地编写它: b = B(a);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM