C++ primer笔记----拷贝控制

1、如果一个构造函数的第一个参数是自身类类型的引用(该引用几乎都是const引用),且任何额外参数都有默认值,则此构造函数是拷贝构造函数

2、即使定义了拷贝构造函数,编译器也会合成一个拷贝构造函数;
拷贝初始化不仅在我们用=定义变量时会发生,在下列情况下也会发生:
将一个对象作为实参传递给一个非引用类型的形参;
从一个返回类型为非引用类型的函数返回一个对象;
用花括号列表初始化一个数组中的元素或一个聚合类的成员;

3、直接初始化:一对小括号加参数。
拷贝初始化:等号右侧对象拷贝到正在创建的对象中,如果需要还需进行类型转换(拷贝初始化没有=号的情况:将一个对象作为实参传递给一个非引用类型的形参时、从一个返回类型非引用类型的函数返回一个对象、用花括号初始化列表初始化一个数组的元素或一个聚合类的成员)

4、重载运算符本质上是函数,其名字由operator关键字后接表示要定义的运算符的符号组成,因此,赋值运算符就是一个名为operator=的函数,重载运算符的参数表示运算符的运算对象;如果一个运算符是一个成员函数,其左侧运算对象就绑定到隐式的this参数;赋值运算符通常应该返回一个指向其左侧运算对象的引用;

5、构造函数初始化对象的非static数据成员,析构函数释放对象使用的资源,并销毁对象的非static数据成员。
析构函数是类的一个成员函数,名字由波浪号接类名构成,它没有返回值,也不接受参数;由于析构函数不接受参数,因此它不能被重载,对一个给定类,只会有唯一一个析构函数。隐式销毁一个内置指针类型的成员不会delete它所指向的对象;

6、什么时候会调用析构函数:
无论何时一个对象被销毁,就会自动调用其析构函数;
变量在离开其作用域时被销毁;
当一个对象被销毁时,其成员被销毁;
容器被销毁时,其元素被销毁;
对于动态分配的对象,当对指向它的指针应用delete运算符时被销毁;
对于临时对象,当创建它的完整表达式结束时被销毁;

7、在构造函数中分配的动态内存对象需要delete;当指向一个对象的引用或者指针离开作用域是,析构函数并不会执行;

8、需要析构函数的类也需要拷贝和赋值操作,合成的析构函数不会delete一个指针数据成员,所以有时我们需要自己定义一个析构函数释放构造函数分配的内存,所以需要析构函数的类,也就需要拷贝构造函数和拷贝赋值运算符,而合成的拷贝构造函数和拷贝赋值运算符只能简单的拷贝指针成员,这就意味着多个对象指向同一个内存,释放多个对象时,造成多次delete;如果一个类需要自定义版本的析构函数,那么肯定是需要自定义的拷贝构造函数和拷贝赋值运算符;拷贝操作和复制操作是相互结合的,如果需要一种,也需要另一种,但不一定意味着需要析构函数

9、类值版本,类的构造函数可能需要动态分配其成员的副本;类值版本,类的拷贝赋值运算符相当于结合了构造函数和析构函数的操作,首先销毁左侧运算对象的资源,再从右侧运算符对象拷贝资源,注意顺序;由于有上述的顺序存在,所以我们必须保证这样的拷贝赋值运算符是正确的:首先将右侧运算对象拷贝到一个临时的对象中,再销毁左侧的运算对象的现有成员,之后将临时对象中的数据成员拷贝至左侧对象中(防范自赋值的情况发生—首先就销毁了自身的成员,再进行拷贝自身则会访问到已经释放的内存中)

10、引用计数:
除了初始化对象外,每个构造函数(拷贝构造函数除外)还要创建一个引用计数,用来记录有多少对象与正在创建的对象共享状态。当我们创建一个对象时,只有一个对象共享状态,因此将计数器初始化为1;
拷贝构造函数不分配新的计数器,而是拷贝给定对象的数据成员,包括计数器。拷贝构造函数递增共享的计数器,指出给定对象的状态又被一个新用户所共享。
析构函数递减计数器,指出共享状态的用户少了一个。如果计数器变为0,则析构函数释放状态。
拷贝赋值运算符递增右侧对象的计数器,递减左侧运算对象的计数器。如果左侧运算对象的计数器变为0,意味着它的共享状态没有用户了,拷贝赋值运算符就必须销毁状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值