- 拷贝控制成员函数:拷贝构造、拷贝赋值、移动构造、移动赋值、析构;不显式定义则编译器会生成合成版本。拷贝和移动构造函数定义了当用同类型的另一个对象初始化本对象时做什么。拷贝和移动赋值运算符定义了将本对象初始化同类型的另一个对象时做什么。析构函数定义了销毁对象时做什么。
13.1 拷贝、赋值与销毁
13.1.1 拷贝构造函数
1.拷贝构造函数:第一个参数是自身类类型的引用(必须是引用),且额外参数有默认值。
- 拷贝初始化发生场景:
1 用 = 号定义变量
2 将一个对象作为实参传递给一个非引用类型的形参。
3 从一个返回类型为非引用类型的函数返回一个对象。
4 用花括号列表初始化一个数组中的元素或一个聚合类的成员。
5 初始化标准库容器或调用其insert或push成员 - 直接初始化与拷贝初始化:直接初始化要求编译器使用普通的函数匹配来选择与我们提供的额参数最匹配的构造函数。拷贝初始化要求编译器将有不运算对象拷贝到正在创建的对象中,如果需要还要进行类型转换。
- 如果拷贝构造函数的参数不是引用类型,则永远不会成功——为了调用拷贝构造函数,我们必须拷贝它的实参,但为了拷贝实参,我们又需要调用拷贝构造函数,如此无线循环。
13.1.2 拷贝赋值运算符
- 重载运算符本质上是函数
13.1.3 析构函数
1.析构函数:释放对象使用资源,并销毁非stastic数据成员;不接受参数,不能重载;先执行函数体,再按初始化的逆序隐式销毁成员;内置指针类型不会delete对象,智能指针是类类型所有可以释放;引用和值指针离开作用域不析构绑定对象。
13.1.4 三五法则
- 三/五法则:5个拷贝控制成员应看作整体,定义了一个则应定义所有。
- 需要拷贝构造函数的类也需要赋值操作,反之亦然。
13.1.6 阻止拷贝
- 阻止拷贝:定义删除的拷贝控制函数;新标准发布前,通常将拷贝控制成员声明为private,并且不定义它们.
- 删除的函数:在函数的参数列表后面加上=delete来指出我们希望将它定义为删除的。
- 析构函数不能是删除的成员。