我试图通过阅读这个博客来理解零规则的含义。它说,如果您声明了自己的析构函数,那么请不要忘记将移动构造函数和移动赋值作为缺省值。
示例
class Widget {
public:
~Widget(); // temporary destructor
... // no copy or move functions
};
“析构函数的添加具有禁用移动函数生成的副作用,但由于Widget是可复制的,用于生成移动的所有代码现在都将生成副本。换句话说,向类添加析构函数可能会导致高效的移动被默认的低效率副本所取代。”
斯科特·迈尔斯( Scott )的上述文字在引文中引起了我的一些疑问:
发布于 2015-11-26 07:49:45
“零规则”实际上是关于生成什么特殊成员函数以及何时生成的其他内容。这是一种对班级设计的某种态度。它鼓励你回答一个问题:
我的班管理资源吗?
如果是这样的话,每个资源都应该转移到它的专用类中,这样您的类就只能管理资源(而不做其他事情),或者只积累其他类和/或执行相同的逻辑任务(但不要管理资源)。
这是比较普遍的单一责任原则的一个特例。
应用它时,您将立即看到,对于资源管理类,您必须定义手动移动构造函数、移动赋值和析构函数(很少需要副本操作)。对于非资源类,您不需要(实际上也不应该)声明任何一个:移动ctor/赋值、复制ctor/赋值、析构函数。
因此,名称中的“零”:当您将类分离到资源管理和其他类时,在“其他”中,您需要提供零个特殊的成员函数(它们将正确地自动生成)。
C++中有一些规则(特定成员函数的定义)会抑制其他定义,但它们只会分散您对零规则核心的理解。
有关更多信息,请参见:
发布于 2015-11-26 07:40:48
通常情况下,如果您有一个析构函数(“做某事”),那么您应该遵循“三的规则”,如果您想要移动语义,它就变成了“五的规则”。
如果您的析构函数为空,则不需要它。因此,这意味着一个非空的析构函数(因为如果不需要的话就不会有一个),那么您还需要在复制和赋值操作中做同样的事情,并且可能的话,移动构造和移动赋值将需要“做一些事情”,而不仅仅是将实际的内容跨。
当然,在某些情况下,这是不正确的,但编译器采用的方法是“仅在析构函数为空时应用自动生成的移动函数”,因为这是“安全”方法。
发布于 2015-11-26 07:45:06
声明/定义Dtor是否只隐藏移动语义,还是复制ctor/复制分配,同时隐藏移动语义?
如果没有为类提供用户定义的移动构造函数,则以下所有内容都是正确的:
然后,编译器将使用signature T::T(T&&)
将移动构造函数声明为其类的非显式内联公共成员。
因此,声明副本构造函数或赋值操作符的yes也隐藏隐式声明的移动构造函数。
https://stackoverflow.com/questions/33932824
复制相似问题