我想重温一下编译器通常自动生成缺省构造函数、复制建构子和赋值运算符的条件。
我记得有一些规则,但我不记得了,也找不到一个有信誉的资源在线。有人能帮忙吗?
在下文中,“自动生成”意味着“隐式声明为默认,但不定义为删除”。在某些情况下,声明了特殊成员函数,但将其定义为删除。
我发现下面的图表非常有用。
来自: 《粘性比特-成为零英雄规则》
C + + 17 N4659标准草案
有关快速的交叉标准参考,请查看以下 cpferences 条目的“隐式声明”部分:
当然,同样的信息也可以从标准中获得,例如 C + + 17 N4659标准草案:
15.8.1“复制/移动构造函数”表示复制建构子:
如果类定义没有显式地声明一个复制建构子,那么就会隐式地声明一个非显式的。 如果类定义声明了 move 构造函数或 move 赋值运算符,则隐式声明的副本 构造函数被定义为已删除; 否则,它被定义为缺省值(11.4) 该类具有用户声明的复制赋值运算符或用户声明的析构函数。
以及 move 构造函数:
8如果类 X 的定义没有显式声明 move 构造函数,那么非显式构造函数将隐式声明 move 构造函数 声明为默认当且仅当 (8.1) ー X 没有用户声明的复制建构子, (8.2) ー X 没有用户声明的拷贝赋值操作符 (8.3) ー X 没有用户声明的移动赋值操作符,并且 (8.4) ー X 没有用户声明的析构函数
8如果类 X 的定义没有显式声明 move 构造函数,那么非显式构造函数将隐式声明 move 构造函数 声明为默认当且仅当
(8.1) ー X 没有用户声明的复制建构子,
(8.2) ー X 没有用户声明的拷贝赋值操作符
(8.3) ー X 没有用户声明的移动赋值操作符,并且
(8.4) ー X 没有用户声明的析构函数
15.8.2“复制/移动赋值操作符”表示复制赋值:
2如果类定义没有显式声明复制赋值运算符,则隐式声明复制赋值运算符。 如果类定义声明了 move 构造函数或 move 赋值运算符,则隐式声明的 拷贝赋值操作符被定义为已删除; 否则,它被定义为默认值(11.4) 如果类具有用户声明的复制建构子或用户声明的析构函数,则不推荐使用 case。
以及移动任务:
4如果类 X 的定义没有显式声明一个移动赋值运算符,那么这个运算符将是隐式的 声明为默认当且仅当 (4.1)ー X 没有使用者声明的复制建构子 (4.2)ー X 没有用户声明的 move 构造函数, (4.3)ー X 没有用户声明的复制赋值操作符,以及 (4.4)ー X 没有用户声明的析构函数。
4如果类 X 的定义没有显式声明一个移动赋值运算符,那么这个运算符将是隐式的 声明为默认当且仅当
15.4“析构函数”指的是析构函数:
如果一个类没有用户声明的析构函数,则一个析构函数被隐式声明为默认值(11.4) 隐式声明的析构函数是其类的内联公共成员。