2016-11-07 58 views
25

VS2015中以下代码的输出是“构造函数”。构造函数是否应该被赋值?

由于缺少赋值运算符,不应该编译失败吗?

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; 
} 
+1

这对你很有用:http://stackoverflow.com/questions/3734247/what-are-all-the-member-functions由编译器创建的一个类似于do-hap- – SenselessCoder

+0

Bu那些不处理任何转换,如从A到B,对吗? – bitwise

+0

哦,我现在看到它了,我认为它是其中之一,B是从A.继承A.道歉。在这种情况下,我认为有一些奇怪的事情发生。这可能是编译器的事情。 – SenselessCoder

回答

29

是的,当有转换正在进行时,就像在你的测试用例中一样。

你有效地调用

b = B(a); 

因为B的赋值操作符B& operator=(B const&)是隐式声明,它重载解析过程中被发现。由于您的分配只是一次转换而不是匹配(并且这恰好是允许发生的转换次数),因此它会将a转换为B,然后将新的临时B分配给b

13

让我们考虑一个类似的例子。

double a; 
int b=5; 

a=b; 

可以分配给一个double的唯一事情是另一个double。但是,int可以转换为double

同样在这里,A可以转换为B,因为这样做的构造函数存在。那就是发生了什么。

+2

那么,你可以给'double'分配一个'int'。这个定义的行为是'int'被隐式转换为'double',并且该转换的结果替换了'double'的存储值。也许最好是说“唯一可以存储在double变量中的是'double'值,或者其他东西。 –

10

您的代码已隐式从A转换为Bb = a编译为b = B(a);。如果你想这是作为错误检测,你可以使用the explicit specifier

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

那么你应该得到的错误,如these generated by 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&&' 

之后,构造函数将永远不会被隐式调用,如果你想打电话给你,你必须明确地写下:b = B(a);

+2

很好的提及'explicit'关键字 – Michael

相关问题