浅度解析深拷贝与浅拷贝问题

1、深拷贝和浅拷贝的原理

当我们使用引用数据类型时,由于引用数据类型他的真实数据是存放在堆区的,而在栈区存储的只是他的地址,例如下图图1所示,

图1

当我们使用编译器提供的拷贝构造函数时,我们拷贝到的只是引用数据类型在栈区的地址,这就造成了两个指针都指向同一块地址,这就是我们所说的浅拷贝,如下图图二所示,当我们改变其中一个指针时,另一个指针所指向的值也会被改变,

图2

但我们又不想要这种情况发生,所以我们可以通过复制一个一模一样的指针(在堆区),这两个指针不共享内容,当新指针改变时,旧指针不会随着改变,这种拷贝也就是深拷贝,如下图图3所示

图3

2、深拷贝和浅拷贝的代码验证证实

当我们创造出一个对象数据类型Person,Person下有这个人的年龄和身高,年龄使用int类型,身高我们用一个指针来存储,并写下他的默认构造函数和有参构造函数还有析构函数,并在构造函数中写上一段话,以便我们后期观察代码执行到那一步了,我们创建一个对象p1,然后我们利用系统默认的拷贝构造函数拷贝p1来创建一个p2,分别输出他们的年龄和身高,

可以看出是可以正常运行的。

但是堆区的空间是需要代码编写人员,手动开辟和手动释放的,我们在有参构造函数中开辟了堆区空间,所以我们需要在析构函数中加入释放堆区空间的函数,但是加了释放堆区空间代码后程序不能运行了,

程序中断结果如图

可以看见p1的析构函数没有运行完毕,所以是析构函数释放空间时出现了错误,这是由于浅拷贝所导致的同一段空间被重复释放的问题,由于浅拷贝p1和p2的身高指针是指向同一处堆区空间的,所以当编译器执行到p2的析构函数时已经将这一块堆区空间给释放了,再执行到p1的析构函数时又要释放一块已经释放了的空间所以造成非法访问,程序中断。(为什么是先执行p2的析构函数再执行p1的析构函数呢,因为栈区空间是先进后出的原则,学过数据结构的同学应该都知道),

我们可以利用自己编写拷贝构造函数解决浅拷贝问题,我们可以在堆区重新开辟一块空间这块空间里的数据和旧空间里的数据一样,然后吧这块空间赋值给p2的身高指针如下图,这就是我们所说的深拷贝,就完美解决了浅拷贝带来的问题。

解决完后运行代码可以正常运行显示

该段代码的浅拷贝原理图如下

该段代码的深拷贝原理图如下

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值