warning C4512: 'B' : assignment operator could not be generated
问题1:为什么会出现这个警告?
引用只能在创建时初始化一次。您不能在创建后重新分配对另一个相同类型变量的引用,因为 Reference 只是为其创建它的类型变量的别名,并将继续如此。尝试重新分配它会产生错误。
通常,编译器默认为每个类生成一个隐式按位赋值运算符,但在这种情况下,由于class B
有一个引用作为成员m_a
,如果编译器要生成一个隐式赋值运算符,它将打破不能重新分配引用的基本规则。因此编译器会生成此警告以通知您它无法生成隐式赋值运算符。
问题 2:但是编译器不应该为 B b1 = b; 生成错误吗?也声明?
生成的警告和这个特定的操作完全没有关系。
B b1 = b;
调用隐式(正如@AndreyT 正确指出的)复制构造函数B::B(const B&)
。隐式复制构造函数是类默认生成的成员函数之一。所以没有警告或错误。
问题3:就像它生成了复制构造函数但没有生成赋值运算符。这两者不是天生就相互联系的吗?
不,它们根本没有关系。是的,编译器生成了一个复制构造函数,但由于上述问题 1 的答案中指定的原因,它无法生成赋值运算符。这是因为成员引用m_a
可以在构造函数本身的主体中初始化。这只是创建时的初始分配,而不是=
.
问题 4:当另一个无法生成时,只为其中一个生成默认实现是否有意义?
对 3 个问题的回答似乎可以回答这个问题。
只是重申您的代码示例中正在执行的操作:
B b(a);
调用转换拷贝构造函数B::B(A&)
B b1 = b;
调用默认拷贝构造函数B::B(const B&)
考虑其他场景。
如果你有B b1 = a;
它会调用B::B(A&)
,因此不会再出现错误。
B::B(A&)
但是如果声明了编译器,编译器会标记一个错误,explicit
并且不允许任何implicit conversions
作为conversion function
.
在这里检查相同。