一、浅拷贝所带来的问题
在我们使用浅拷贝的时候会出现以下两个问题
- 会析构两次
- 一个对象修改会影响另外一个
二、问题一的解决方案(引用计数)
我们可以使用引用计数的方法来规避这个问题
这种方法的思路是设置一个变量来获取当前有多少个对象管理着同一块空间,当且仅当引用计数为1时,才调用析构函数处理掉这块空间。
三、问题二的解决方案(写时拷贝)
我们的思路是这样的,我们先是浅拷贝,但是需要有引用计数,当引用计数大于1的时候,只要涉及到修改某个对象,那么就对该对象进行深拷贝。如果不需要修改,那么保持浅拷贝
这种方案也称作延时拷贝
四、vs中对对象做出的一些处理
我们来看这段代码的运行结果
void teststring9() { std::string s("hello world"); cout << sizeof(s) << endl; }
那么这是为什么呢?这个数怎么这么奇怪呢?
实际上,这是因为vs对这个对象做了一个以空间换时间的处理
vs给每个对象加了一个长度为16的buff数组。
当对象的长度不足16的时候,不需要开空间,直接放到这个数组中,当长度大于等于16的时候才进行开空间。
故16+4+4+4就是28
五、总结
这两种解决方案的本质其实就是延时拷贝,本质是一种博弈。因为引用计数的代价并不是很大。相当于赌的就是只要有大部分对象不会进行修改,就是赚了!!!