浅拷贝&深拷贝&引用计数

当类里面有对象时,进行简单的赋值的浅拷贝,当s1和s2中包含的指针对象同时指向一块内存,析构时delete了两次这个内存,会出错, 存在崩溃的问题。这里我们需要深拷贝。
这里写图片描述

这里写图片描述
构造s2时拷贝一块跟s1指向数据块一样大的数据块,并将值拷贝下来,这样s1和s2指向各自的数据块,析构时释放各自的数据块。

浅拷贝存在析构多次的问题,深拷贝又会浪费空间,有没有更好一点的方法呢?
为了解决浅拷贝中同一块内存被析构多次的问题,我们引入了引用计数:
引用计数:不同对象共享同样的内存,同时对象能够自己跟踪自己被引用多少次,能够在没有被继续引用的时候删除自己,保证了没有内存泄露的情况。

这里写图片描述
在引用计数中,每一个对象负责维护对象所有引用的计数值。当一个新的引用指向时,引用计数器就递增,当去掉一个引用时,引用计数就递减。当引用计数到零时,该对象就将释放占有的资源。最直观的垃圾收集是引用计数。引用计数很简单,但是需要编译器的重要配合,并且增加了赋值函数的开销。

要实现这个计数器:
1.可以多开四个字节的空间
这里写图片描述

2.也可以加一个成员变量指向一段动态开辟的内存
这里写图片描述

优缺点:引用计数能解决浅拷贝中的析构问题。它也是有缺点的,比如当两个线程同时指向同一块内存,引用计数同时++,本应加两次,可能因为同时加会少加一次。在析构时少析构一次,必然就会出现野指针了。

引用计数的应用:一种是大量的对象共享少数的内存,一种是同样的内存只被共享几次,也就是基本没几次共享,显然前者更适合用引用计数。比如,目标对象消耗大量的资源,资源的分配和释放很昂贵。高度共享:由于使用拷贝构造函数和赋值操作符,所以引用计数可能比较大;引用的创建和清除相对度低。如果程序中出现大量的对象创建和释放时,使用引用计数的效果反而更差而出现大量的对象的赋值操作更适合引用计数的使用。

猜你喜欢

转载自blog.csdn.net/qq_40995354/article/details/81225283
今日推荐