首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么析构函数禁用隐式移动方法的生成?

为什么析构函数禁用隐式移动方法的生成?
EN

Stack Overflow用户
提问于 2015-11-26 07:29:38
回答 4查看 4K关注 0票数 21

我试图通过阅读这个博客来理解零规则的含义。它说,如果您声明了自己的析构函数,那么请不要忘记将移动构造函数和移动赋值作为缺省值。

示例

代码语言:javascript
运行
复制
class Widget {
public:
  ~Widget();         // temporary destructor
  ...                // no copy or move functions
};

“析构函数的添加具有禁用移动函数生成的副作用,但由于Widget是可复制的,用于生成移动的所有代码现在都将生成副本。换句话说,向类添加析构函数可能会导致高效的移动被默认的低效率副本所取代。”

斯科特·迈尔斯( Scott )的上述文字在引文中引起了我的一些疑问:

  • 为什么声明析构函数隐藏移动语义?
  • 声明/定义析构函数是否只隐藏移动语义或复制构造函数,以及复制赋值是否也隐藏移动语义?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-11-26 07:49:45

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

我的班管理资源吗?

如果是这样的话,每个资源都应该转移到它的专用类中,这样您的类就只能管理资源(而不做其他事情),或者只积累其他类和/或执行相同的逻辑任务(但不要管理资源)。

这是比较普遍的单一责任原则的一个特例。

应用它时,您将立即看到,对于资源管理类,您必须定义手动移动构造函数、移动赋值和析构函数(很少需要副本操作)。对于非资源类,您不需要(实际上也不应该)声明任何一个:移动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/
票数 24
EN

Stack Overflow用户

发布于 2015-11-26 07:40:48

通常情况下,如果您有一个析构函数(“做某事”),那么您应该遵循“三的规则”,如果您想要移动语义,它就变成了“五的规则”。

如果您的析构函数为空,则不需要它。因此,这意味着一个非空的析构函数(因为如果不需要的话就不会有一个),那么您还需要在复制和赋值操作中做同样的事情,并且可能的话,移动构造和移动赋值将需要“做一些事情”,而不仅仅是将实际的内容跨。

当然,在某些情况下,这是不正确的,但编译器采用的方法是“仅在析构函数为空时应用自动生成的移动函数”,因为这是“安全”方法。

票数 6
EN

Stack Overflow用户

发布于 2015-11-26 07:45:06

声明/定义Dtor是否只隐藏移动语义,还是复制ctor/复制分配,同时隐藏移动语义?

如果没有为类提供用户定义的移动构造函数,则以下所有内容都是正确的:

  • 没有用户声明的副本构造函数。
  • 没有用户声明的副本分配操作符。
  • 没有用户声明的移动赋值操作符。
  • 没有用户声明的析构函数。

然后,编译器将使用signature T::T(T&&)将移动构造函数声明为其类的非显式内联公共成员。

因此,声明副本构造函数或赋值操作符的yes也隐藏隐式声明的移动构造函数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33932824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档