移动构造函数和移动赋值运算符
一、特种函数
特种函数:C++自行生成的成员函数。
C++98的4个特种成员函数:默认构造函数(无参),析构函数、复制构造函数、复制赋值函数。
特种函数都具有public访问层级,都是inline,非虚的。只有在类中没有声明任何对应的函数,编译期才会自动生成。
class Widget {
public:
Widget();//默认构造函数
~Widget(); //默认析构函数
Widget(const Widget& w); //默认复制构造函数
Widget& operator=(const Widget& w);//默认复制赋值函数
};
在C++11之后又加入了两个新的特种函数:
Widget(Widget&& w);//移动构造函数
Widget& operator=(Widget&& w);//移动赋值运算符
二、移动与复制
按成员移动分两部分:
1、在支持移动操作的成员上执行移动操作;
2、在不支持移动操作的成员上执行复制操作。
若发生了复制操作,则移动操作就不会在已有声明的前提下被生成。
两种复制操作是独立的:声明了其中一个不会阻止编译器生成另一个;
两种移动操作不彼此独立:声明了其中一个会阻止编译器生成另一个。
一旦显示声明了复制操作,此类便不再生成移动操作,反之亦然。
大三律:若声明了复制构造函数、复制赋值运算符、析构函数中的任意一个,则这三个都需要同时被声明。
移动操作的生成条件:
1、该类未声明任何复制操作;
2、该类未声明任何移动操作;
3、该类未声明任何析构函数。
注:“=default” 用来表示使用系统自动生成的成员函数。
三、C++98与C++11在特征函数的区别
1、默认构造函数:与C++98相同,仅当类中不包含用户声明的构造函数时生成。
2、析构函数:与C++98基本相同。区别在于析构函数默认为noexcept。仅当基类的析构函数为虚,派生类的析构函数才为虚。
3、复制构造函数:运行期与C++98相同:按成员进行非静态数据成员的复制构造。仅当类中不包含用户声明的复制构造函数时生成。若该类声明了移动操作,则复制构造函数将被删除,已存在复制赋值或析构函数,则被废弃。
4、复制赋值运算符:运行期和C++98相同:按成员进行非静态数据成员的复制赋值,其他与3类似。
5、移动操作:都按成员进行费静态数据成员的移动操作。仅当满足三个条件时才生成。
注:成员函数模板在任何情况下都不会抑制特种成员函数的生成。