Xeo*_*Xeo 325 c++ constructor rvalue-reference rule-of-three c++11
因此,在观看了关于右值引用的精彩演讲之后,我认为每个类都会受益于这样的"移动构造函数",template<class T> MyClass(T&& other)
编辑,当然还有"移动赋值运算符",template<class T> MyClass& operator=(T&& other)
正如Philipp在他的回答中指出的,如果它已经动态分配成员,或通常存储指针.就像你应该有一个copy-ctor,赋值运算符和析构函数,如果之前提到的点适用.思考?
Phi*_*ipp 313
我要说三法则成为三,四,五的规则:
每个类应明确定义以下一组特殊成员函数:
- 没有
- 析构函数,复制构造函数,复制赋值运算符
此外,显式定义析构函数的每个类可以显式定义移动构造函数和/或移动赋值运算符.
通常,以下一组特殊成员函数是明智的:
- 无(对于许多隐式生成的特殊成员函数正确且快速的简单类)
- 析构函数,复制构造函数,复制赋值运算符(在这种情况下,类不可移动)
- 析构函数,移动构造函数,移动赋值运算符(在这种情况下,该类将不可复制,对于底层资源不可复制的资源管理类很有用)
- 析构函数,复制构造函数,复制赋值运算符,移动构造函数(因为复制省略,如果复制赋值运算符按值获取其参数,则没有开销)
- 析构函数,复制构造函数,复制赋值运算符,移动构造函数,移动赋值运算符
请注意,不会为显式声明任何其他特殊成员函数的类生成移动构造函数和移动赋值运算符,不会为显式声明移动构造函数或移动的类生成复制构造函数和复制赋值运算符赋值运算符,并且具有显式声明的析构函数和隐式定义的复制构造函数或隐式定义的复制赋值运算符的类被视为已弃用.特别是,以下完全有效的C++ 03多态基类
class C {
virtual ~C() { } // allow subtype polymorphism
};
Run Code Online (Sandbox Code Playgroud)
应改写如下:
class C {
C(const C&) = default; // Copy constructor
C(C&&) = default; // Move constructor
C& operator=(const C&) = default; // Copy assignment operator
C& operator=(C&&) = default; // Move assignment operator
virtual ~C() { } // Destructor
};
Run Code Online (Sandbox Code Playgroud)
有点烦人,但可能比替代(自动生成所有特殊成员函数)更好.
与三巨头规则相反,未遵守规则可能会造成严重损害,未明确声明移动构造函数和移动赋值运算符通常很好,但在效率方面通常不是最理想的.如上所述,只有在没有显式声明的复制构造函数,复制赋值运算符或析构函数时,才会生成移动构造函数和移动赋值运算符.对于自动生成复制构造函数和复制赋值运算符,这与传统的C++ 03行为不对称,但更安全.因此,定义移动构造函数和移动赋值运算符的可能性非常有用,并创建了新的可能性(纯粹的可移动类),但遵循C++ 03三巨头规则的类仍然可以.
对于资源管理类,如果无法复制基础资源,则可以将复制构造函数和复制赋值运算符定义为已删除(计为定义).通常你仍然想要移动构造函数和移动赋值运算符.复制和移动赋值运算符通常使用swap
,如在C++ 03中实现.如果你有一个移动构造函数和移动赋值运算符,则特殊化std::swap
将变得不重要,因为泛型std::swap
使用移动构造函数并移动赋值运算符(如果可用),并且应该足够快.
不用于资源管理的类(即,没有非空的析构函数)或子类型多态(即,没有虚拟析构函数)应该不声明五个特殊成员函数; 它们都将自动生成并且行为正确且快速.
NoS*_*tAl 68
我无法相信没有人与此有关.
基本上,文章认为"零法则".我引用整篇文章是不合适的,但我认为这是重点:
具有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符的类应专门处理所有权.其他类不应该有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符.
这一点是恕我直言的重要:
常见的"包中所有"类包含在标准库中:
std::unique_ptr
和std::shared_ptr
.通过使用自定义删除对象,两者都具有足够的灵活性来管理几乎任何类型的资源.
peo*_*oro 14
是的,我认为为这些类提供移动构造函数会很好,但请记住:
这只是一种优化.
仅实现一个或两个复制构造函数,赋值运算符或析构函数可能会导致错误,而没有移动构造函数可能会降低性能.
无需修改即可始终应用移动构造函数.
有些类总是分配它们的指针,因此这些类总是在析构函数中删除它们的指针.在这些情况下,您需要添加额外的检查,以确定其指针是已分配还是已被移走(现在为空).
以下是自2011年1月24日以来当前状况及相关发展的简短更新.
根据C++ 11标准(见附件D的[depr.impldec]):
如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用复制构造函数的隐式声明.如果类具有用户声明的复制构造函数或用户声明的析构函数,则不推荐使用复制赋值运算符的隐式声明.
它实际上被提议废弃被弃用的行为,使C++ 14成为真正的"五规则",而不是传统的"三规则".2013年,EWG投票反对该提案将在C++ 2014中实施.决定该提案的主要理由与对破坏现有代码的普遍关注有关.
最近,已提出再适应C++ 11的措辞,从而达到五非正式规则,即
如果用户提供了这些函数中的任何一个,则不能编译生成复制函数,移动函数或析构函数.
如果得到EWG的批准,C++ 17可能会采用"规则".
归档时间: |
|
查看次数: |
65296 次 |
最近记录: |