为什么析构函数会禁用隐式移动方法的生成? [英] Why does destructor disable generation of implicit move methods?

查看:140
本文介绍了为什么析构函数会禁用隐式移动方法的生成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过阅读此博客,我试图了解零规则的含义. . IMO,它说,如果您声明自己的析构函数,那么不要忘记将move构造函数和move分配设为默认值.

示例:

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

添加析构函数具有禁用的副作用 移动功能的生成,但是由于小部件是可复制的,因此所有 现在,用于生成移动的代码将生成副本.在 换句话说,在类中添加析构函数会导致 高效的举动将被默默地取代 可能是效率较低的副本".

斯科特·迈耶斯(Scott Meyers)的上述文字在引号内引起了我的一些疑问:

  • 为什么声明析构函数隐藏了移动语义?
  • 声明/定义析构函数仅隐藏移动语义或复制 构造函数和副本分配还隐藏了移动语义?

解决方案

零规则"实际上与生成什么特殊成员函数以及何时生成其他内容无关.这是关于班级设计的某种态度.它鼓励您回答一个问题:

我的课程可以管理资源吗?

如果是这样,则应将每个资源移至其专用的类,以便您的类仅管理资源(不执行其他操作)或仅累积其他类和/或执行相同的逻辑任务(但不管理资源)./p>

这是更普遍的单一责任原则的特例.

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

因此将名称命名为零":当您将类与资源管理和其他类分开时,在其他"中,您需要提供零个特殊成员函数(它们将自动正确生成.)

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

有关更多信息,请参见:

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

I was trying to understand what the rule of zero says by reading this blog. IMO, it says if you declare your own destructor then don't forget to make the move constructor and move assignment as default.

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".

The above text by Scott Meyers, inside the quotes raise some questions in my mind:

  • Why declaring destructor hides the move semantics?
  • Is declaring/definig destructor only hides the move semantics or copy constructor and copy assignment as well hides the move semantics?

解决方案

"The Rule of Zero" is in fact about something else than what special member functions are generated and when. It is about a certain attitude to class design. It encourages you to answer a question:

Does my class manage resources?

If so, each resource should be moved to its dedicated class, so that your classes only manage resources (and do nothing else) or only accumulate other classes and/or perform same logical tasks (but do not manage resources).

It is a special case of a more general Single Responsibility Principle.

When you apply it, you will immediately see that for resource-managing classes you will have to define manually move constructor, move assignment and destructor (rarely will you need the copy operations). And for the non-resource classes, you do not need to (and in fact you probably shouldn't) declare any of: move ctor/assignment, copy ctor/assignment, destructor.

Hence the "zero" in the name: when you separate classes to resource-managing and others, in the "others" you need to provide zero special member functions (they will be correctly auto-generated.

There are rules in C++ what definition (of a special member function) inhibits what other definitions, but they only distract you from understanding the core of the Rule of Zero.

For more information, see:

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

这篇关于为什么析构函数会禁用隐式移动方法的生成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆