【发布时间】:2015-10-28 14:20:23
【问题描述】:
目前我阅读了 Scott Meyers 的Effective Modern C++ 一书,现在我处于:第 17 项:了解特殊成员函数生成。我>
我的误解来自以下部分(理由):
这两个复制操作是独立的:声明一个不会阻止编译器生成另一个。因此,如果您声明了一个复制构造函数,但没有复制赋值运算符,然后编写需要复制赋值的代码,编译器将为您生成复制赋值运算符。同样,如果您声明了一个复制赋值运算符,但没有复制构造函数,但您的代码需要复制构造,编译器将为您生成复制构造函数。在 C++98 中是这样,在 C++11 中仍然如此。
这两个移动操作不是独立的。如果您声明其中一个,则会阻止编译器生成另一个。 基本原理是,如果你为你的类声明一个移动构造函数,你就表明应该如何实现移动构造,这与编译器生成的默认成员移动不同。如果成员移动构造有问题,那么成员移动分配也可能有问题。因此,声明移动构造函数可防止生成移动赋值运算符,而声明移动赋值运算符可防止编译器生成移动构造函数。
我认为基本原理部分也可以应用于 copy constructor 和 copy assignment operator 对,不是吗?因此,如果我声明一个复制构造函数,我会用它表明默认的成员复制对我来说是不够的。如果我这么说,那么复制赋值运算符也应该是用户定义的。
我认为这是一本很棒的书,但在这一点上,我还不清楚这个理由。请帮我解释一下。谢谢。
【问题讨论】:
-
向后兼容是原因。值得注意的是,不推荐在用户声明复制操作(或析构函数)时隐式生成复制操作。
-
是的,应该是这样的。用户声明的复制构造函数应防止复制赋值运算符的隐式声明,反之亦然。类似地,用户声明的析构函数应该防止隐式声明这两个复制特殊成员,C++11 弃用了这些情况。但是完全取消它们会破坏很多现有代码。
标签: c++ copy-constructor move-semantics copy-assignment