类的特种函数生成机制
规则
参考Effective Morder C++上的说明:
- 默认构造函数:仅当类中不包含用户声明的构造函数时才生成。
- 析构函数:默认生成,当基类的析构函数为虚时,派生类的默认析构函数为虚函数。
- 拷贝构造函数:仅当类中不包含用户声明的拷贝构造函数时才生成。如果该类声明了移动操作,那么拷贝构造函数将被定义为删除的。
- 拷贝赋值运算符:仅当类中不包含用户声明的拷贝赋值运算符时才生成。如果该类声明了移动操作,那么拷贝赋值运算符将被定义为删除的。
- 移动构造函数和移动赋值运算符:仅当类中不包含用户声明的拷贝操作、移动操作和析构函数时才生成。
例子:A BUG
因为不熟悉析构函数的生成机制,导致了一个BUG。
首先,下面的代码没有问题,因为数据成员m_是只移型别——std::thread,所以Widget默认也是个只移型别;mm中也可以插入一个由只移型别构造的std::pair<int, Widget>,因为pair默认支持右值参数构造(可以由只移的Widget构造)和自身的移动构造函数(可以移动构造到unordered_map中):
class Widget {
public:
Widget() = default;
private:
std::thread m_; // 只移型别
};
unordered_map<int, Widget> mm;
mm.insert({
12, Widget()});
然后,我手贱加了一个默认的析构函数:
class Widget {
public:
Widget() =