本文主要介绍 C++11 之后编译器自动为类生成的函数,以及新的生成规则
编译器自动为类生成的函数
在 C++ 中,如果我们定义了一个空类
1 | class Dog {}; |
编译器会自动为这个类生成构造函数、析构函数等。具体来说,我们定义了以上的一个 Dog
类,编译器会将它补全成一个如下自带6个函数的类:
1 | class Dog { |
自动生成函数规则
然而,并不是所有情况下,编译器都会生成所有6个函数 —— 假如用户定义了某种类型的构造函数,编译器则不会生成某种其他类型构造函数。自动函数生成遵循以下规则:
- 默认构造函数:只在用户没有定义其它类型构造函数时才会生成
- 拷贝构造函数:只有用户没有定义 移动构造函数(5) 和 移动赋值运算符(6) 时,才会生成
- 拷贝赋值运算符:只有用户没有定义 移动构造函数(5) 和 移动赋值运算符(6) 时,才会生成
- 析构函数:无限制
- 移动构造函数:只有用户没有定义 拷贝构造函数(2), 拷贝赋值运算符(3), 析构函数(4) 和 移动赋值运算符(6) 时,才会生成
- 移动赋值运算符:只有用户没有定义 拷贝构造函数(2), 拷贝赋值运算符(3), 析构函数(4) 和 移动构造函数(5) 时,才会生成
例如,如果我们定义一个带有拷贝构造函数的类
1 | class Cat { |
另一个例子:
1 | class Duck { |
在实践中,这个特性非常有用 —— 有些资源只应该被移动而不应该被拷贝,mutex
、socket
等
构造函数带默认值的例子:
1 | class Frog { |
在这个例子中当第二个函数不存在时,Frog 是通过 Frog 右值构造的,因此 Frog(Frog &&, int = 0)
函数是移动构造函数,同理有:
1 | class Frog { |