c++ - 为什么析构函数禁用隐式 move 方法的生成?

标签 c++ c++11 destructor move rule-of-zero

我试图通过阅读 this blog 来理解零规则的含义. IMO,它说如果您声明自己的析构函数,那么不要忘记将 move 构造函数和 move 赋值设置为默认值。

Example :

class Widget {
public:
  ~Widget();         // temporary destructor
  ...                // no copy or move functions
};

"The addition of the destructor has the side effect of disabling generation of the move functions, but because Widget is copyable, all the code that used to generate moves will now generate copies. In other words, adding a destructor to the class has caused presumably-efficient moves to be silently replaced with presumably-less-efficient copies".

上面引用的 Scott Meyers 的文字在我的脑海中提出了一些问题:

  • 为什么声明析构函数会隐藏 move 语义?
  • 声明/定义析构函数仅隐藏 move 语义或复制 构造函数和复制赋值也隐藏了 move 语义?

最佳答案

“零法则”实际上不是关于生成什么特殊成员函数以及什么时候生成的。讲的是对类设计的某种态度。它鼓励你回答一个问题:

我的类(class)管理资源吗?

如果是这样,应将每个资源移至其专用类,以便您的类仅管理资源(不做任何其他事情)或仅累积其他类和/或执行相同的逻辑任务(但不管理资源)。

这是更一般的单一职责原则的特例。

应用它时,您会立即看到,对于资源管理类,您必须手动定义 move 构造函数、 move 赋值和析构函数(很少需要复制操作)。对于非资源类,您不需要(实际上您可能不应该)声明以下任何一项: move 构造函数/赋值、复制构造函数/赋值、析构函数。

因此名称中的“零”:当您将类与资源管理和其他类分开时,在“其他”中您需要提供零个特殊成员函数(它们将被正确地自动生成。

C++ 中有一些规则(特殊成员函数的)定义会禁止其他定义,但它们只会分散您对零规则核心的理解。

有关详细信息,请参阅:

  1. https://akrzemi1.wordpress.com/2015/09/08/special-member-functions/
  2. https://akrzemi1.wordpress.com/2015/09/11/declaring-the-move-constructor/

关于c++ - 为什么析构函数禁用隐式 move 方法的生成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52351135/

相关文章:

c++ - 匿名命名空间的 GCC 缺陷?

c++ - 错误 C2039 : 'vector' : is not a member of 'std'

c++ - C++向 vector 添加对象会破坏早期的对象

python - 构造函数和析构函数如何工作?

c++ - 开源 C++ 游戏引擎数学库?

c++ - std::string 和 std::vector<char> 有什么区别?

c++ - 即使 XZY 具有非复制约束,构造助手 make_XYZ 也允许 RVO 和类型推导

c++ - 如何修复我的代码中的无限循环?我认为它跳过了第二个 cin 所以它一直在循环

c++ - 可变参数模板是潜在的代码膨胀吗?

c++ - 销毁对象放置新后未调用析构函数