关于C++的拷贝(学习笔记03)

所谓拷贝,是对类的一种复制,不同于一个数值的复制,类中成员更加复杂,这时就会用到拷贝构造函数,下面简要说明其必要性:

首先,上图左是以传值的方式传递对象,而我们不难发现,创建一个类(A a;)的时候,a在堆区,而若想要传递参数,需要在栈区再次创建一个类,此时需要拷贝的功能;

同理,上图右也不能直接将类aA直接按传值的方式返回对象,故这种情况下我们需要一个拷贝的功能;

1)拷贝构造函数

拷贝和赋值有所不同,拷贝要做的是:从无到有的创建一个新的对象,这一点不同于赋值(如上图右侧赋值前,a1a2已经存在,而拷贝过程构造前b2b3不存在); 

还有一点要注意的是,拷贝构造函数的上图两种写法中(B b2(b1);和B b3 = b1)我们建议在类的拷贝时选用第一种写法,这样更易于区分;

2)缺省拷贝构造函数

 拷贝构造函数主要有两种形式,一个是自定义拷贝构造函数,另一个是缺省的拷贝构造函数,我们在这里先讨论缺省拷贝构造函数

在用户没有自定义一个拷贝构造函数的时候,由编译器会提供一个缺省的拷贝构造函数,我们需要了解的是,缺省的拷贝构造函数访问控制是public的,方式是“浅”拷贝(下面要介绍的);

3)浅拷贝

 浅拷贝在拷贝的过程中,对于静态数据成员是不能够拷贝的,在上图左的其他几项,是浅拷贝的拷贝范围;

值得注意的是,在一般情况下,我们采用的浅拷贝是按位进行传值的,但若成员是一个类,如上图右侧,AA mAA 这一个式子中就是一个对象数据成员,他在浅拷贝的过程中是会自动调用所属类(本例中为类AA)的拷贝构造函数的;

 当然,浅拷贝在有些时候会有不足:

上图中,在创建类b1b2时,用到了拷贝,并且由于指针的地址值也被拷贝,故b1b2中的pA指向了相同的对象,然而,在我们释放内存的时候,会发现在清理b2的时候,A类对象就已经被释放掉了,这样在清理b2的时候,pA就没有指向的位置了,这时运行会报错--“访问非法数据”

4)自定义的拷贝构造函数

 与浅拷贝相对应,我们讨论的是深拷贝:
1、好处在于可以按找我们的意愿去实现拷贝;

2、实现深拷贝,只能通过自定义的方式实现;

如上图,和之前举例类似,只不过多加了自定义拷贝构造函数,即图右蓝色部分,上下分为两种写法,但含义相同;

这样写的好处就是在进行拷贝的时候,对指针指向的内容也会复制,不会出现前面访问错位的问题;

需要注意:拷贝构造函数也是构造函数的一种,在其初始化列表中也要对引用类型进行初始化,才不会出现报错(如上图右数据成员有&rA,需要在初始化列表中写出人A(b,rA))

在如下情况会用到拷贝构造函数

需要多说一点的是禁止拷贝

可以选择将拷贝构造函数写到private中,可以禁止类外的拷贝,但若想完全禁止,则需要如下俩条写法:

 -------------------END--------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值