标签:个数 delete 编译 变量 默认构造函数 拷贝 3.1 部分 操作
1.拷贝构造函数
基本形式:Name(const Name&)
对于类类型成员,会调用拷贝构造函数拷贝,对于内置类型成员就直接拷贝。对于数组,合成的拷贝构造函数会逐个拷贝都另一个数组中(内置类型)。
拷贝构造函数发生的时候:
- 发生在用 = 定义变量时
- 将一个对象作为实参传递给一个非引用类型的形参
- 从一个返回类型为非饮用类型的函数返回一个对象
- 用花括号列表初始化一个数组中的元素或一个聚合类中的成员
注意:拷贝构造函数第一个参数必须是自身的引用,因为拷贝构造函数是用来初始化非引用类类型参数,如果参数不是自身的引用,那么不会调用成功,会无限循环。为了调用拷贝构造函数会拷贝实参,这样又会调用拷贝构造函数。
2.拷贝赋值运算符(出现在赋值时)
基本形式:Name& operator = (const Name&)
通常来说应该返回指向指向左侧运算对象的引用。会将右侧非static对象赋值给左侧成员。合成的拷贝赋值运算符会逐个赋值数组元素(内置类型)。
3.析构函数
释放对象使用的资源,并销毁对象的非static数据成员。
析构函数发生的时候:
- 变量在离开其作用域时被销毁
- 当一个对象被销毁时,其成员被销毁
- 容器被销毁时,其元素被销毁(包括数组)
- 动态分配的对象,当对指向它的指针应用delete运算符时被销毁
- 临时对象,当创建它的完整表达式结束时被销毁(作用域)
注意:析构函数自身并不销毁成员,成员是在析构函数体之后隐含析构阶段中被销毁的。在整个对象销毁过程中,析构函数体是作为成员销毁步骤之外的另一部分而进行的。
4.三五法则
1.需要析构函数的类需要拷贝和赋值操作
2.需要拷贝操作的类也需要赋值操作
5.使用 = default
可以在拷贝控制成员定义为如下:
Name() = default; //默认构造函数
Name(const Name&) = default;
Name& operator = (const Name&) = default;
~Name() = default;
来显示说明使用编译器合成版本。
6.使用 = delete
也可以如下定义:
Name() = delete; //默认构造函数
Name(const Name&) = delete;
Name& operator = (const Name&) = delete;
析构函数不能声明为被删除
来说明阻止的拷贝赋值操作(老标准可以把这些放进private阻止拷贝)。对于某些类来说,拷贝赋值操作没有意义。
注意:= delete必须出现在函数第一次声明的时候,而 = default直到编译器生成代码时才需要。同时也可以对其他任何函数使用= delete。
7.合成的拷贝控制成员可能是删除的
出现以下情况,合成的拷贝控制成员会被定义为删除:
- 如果类的某个成员的析构函数是删除的或不可访问,则析构函数被定义为删除
- 如果类的某个成员的拷贝构造函数是删除的或不可访问的,则类的合成拷贝构造函数被定义为删除的。
- 如果类的某个成员的析构函数是删除的或不能不可访问的,则类的合成拷贝构造函数也定义为删除的。
- 如果类的某个成员的拷贝赋值运算符是删除的或不可访问的,或是类有一个const或引用成员,则类的合成拷贝赋值运算符被定义为删除的。
- 如果类的某个成员的析构函数是删除的或不可访问的,或是类有一个引用成员,它没有类内初始化器,或是类有一个const成员,它没有类内初始化器且其类型未显示定义默认构造函数,则该类的默认构造函数被定义为删除的。
C++ primer 13.1:拷贝、赋值和析构
标签:个数 delete 编译 变量 默认构造函数 拷贝 3.1 部分 操作
原文地址:http://www.cnblogs.com/CoderZSL/p/7617134.html