【问题标题】:Generated copy and move operators?生成的复制和移动操作符?
【发布时间】:2015-10-28 14:20:23
【问题描述】:

目前我阅读了 Scott MeyersEffective Modern C++ 一书,现在我处于:第 17 项:了解特殊成员函数生成。我>

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

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

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

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

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

【问题讨论】:

  • 向后兼容是原因。值得注意的是,不推荐在用户声明复制操作(或析构函数)时隐式生成复制操作。
  • 是的,应该是这样的。用户声明的复制构造函数应防止复制赋值运算符的隐式声明,反之亦然。类似地,用户声明的析构函数应该防止隐式声明这两个复制特殊成员,C++11 弃用了这些情况。但是完全取消它们会破坏很多现有代码。

标签: c++ copy-constructor move-semantics copy-assignment


【解决方案1】:

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

当然。该标准与您一致。在 [class.copy] 中:

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

还有:

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

当然,如果立即删除相关的“后一种情况”,可能会有很多现有代码会中断,这就是为什么标准首先弃用,并且只会在未来。

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

【讨论】:

  • 为什么它不是第一个 C++ 标准的一部分?
猜你喜欢
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
相关资源
最近更新 更多