2

目前我正在阅读Scott Meyers的《 Effective Modern C++ 》一书,现在我在:第 17 条:理解特殊成员函数生成。

我的误解来自以下部分(理由):

这两个复制操作是独立的:声明一个不会阻止编译器生成另一个。因此,如果您声明了一个复制构造函数,但没有复制赋值运算符,然后编写需要复制赋值的代码,编译器将为您生成复制赋值运算符。同样,如果您声明了一个复制赋值运算符,但没有复制构造函数,但您的代码需要复制构造,编译器将为您生成复制构造函数。这在 C++98 中是正确的,在 C++11 中仍然是正确的。

这两个移动操作不是独立的。如果您声明其中一个,则会阻止编译器生成另一个。基本原理是,如果你为你的类声明一个移动构造函数,你就表明应该如何实现移动构造,这与编译器生成的默认成员移动不同。如果成员移动构造有问题,那么成员移动分配也可能有问题。因此,声明移动构造函数可防止生成移动赋值运算符,而声明移动赋值运算符可防止编译器生成移动构造函数。

我认为基本原理部分也可以应用于复制构造函数复制赋值运算符对,不是吗?因此,如果我声明一个复制构造函数,我会用它表明默认的成员复制对我来说是不够的。如果我这么说,那么复制赋值运算符也应该是用户定义的。

我认为这是一本很棒的书,但在这一点上,我还不清楚这个理由。请帮我解释一下。谢谢。

4

1 回答 1

3

我认为基本原理部分也可以应用于复制构造函数和复制赋值运算符对,不是吗?

绝对地。该标准与您一致。在 [class.copy] 中:

如果类定义未显式声明复制构造函数,则隐式声明非显式构造函数。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况。

和:

如果类定义没有显式声明复制赋值运算符,则隐式声明一个。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制赋值运算符被定义为删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制构造函数或用户声明的析构函数,则不推荐使用后一种情况。

当然,如果立即取消所讨论的“后一种情况”,可能会有很多现有代码会中断,这就是标准首先弃用的原因,并且只会在未来任意遥远的时间点将其删除。

话又说回来,即使是长期被弃用和删除的功能也有一种在他们不受欢迎的情况下长期存在的方式。喜欢char * s = "MyString";

于 2015-08-05T17:27:25.260 回答