博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
引用计数
阅读量:6265 次
发布时间:2019-06-22

本文共 1848 字,大约阅读时间需要 6 分钟。

什么是引用计数?

一个在堆上创建的对象,记录有多少个指针指向它。


 为什么要设计引用计数,他解决什么问题?

1、new出一个临时对象,使用完了,需要delete。但是拥有权会转移(auto_ptr)或者扩散,因此很难确定delete时机。忘记delete导致资源泄漏,过早delete,导致还在使用的指针出现错误,重复delete导致未定义行为。

2、许多对象拥有相同的值,存储多次是个很愚蠢的事,可以共享。


如何实现:

1、以String为例说明,String s1 = "Hello", String s2 = s1; 可以让s1,s2共享"Hello"。

2、引用计数放在哪里呢?显然不能放在String对象中,因为每个String对象都有这个引用计数,引用计数应该和String指向的Value在一起。

3、在String中建立一个嵌套类StringValue,String中有一个字段 StringValue* pStringValue。为什么StringValue设计成嵌套类,因为StringValue只是嵌套在String中,为了实现String,不会出现在其他地方。与此类似的有,STL中各种容器专属的迭代器。

4、StringValue中有:int refCount,记录引用计数。char* pData:指向char。

5、String的copy构造

1 String::String(const String& rhs)2     :pStringValue(rhs.pStringValue)3 {4     ++(pStringValue->refCount);5 }

6、String的copy赋值

1 String& String::operator =(const String& rhs) 2 { 3     if(pStringValue == rhs.pStringValue) //共享的数据赋值 4     { 5         return *this; 6     } 7      8     if(--pStringValue->refCount == 0) //处理老的内容 9     {10         delete pStringValue;11     }12     13     pStringValue = rhs.pStringValue;14     ++pStringValue->refCount;15     16     return *this;17 }

7、String的析构

1 String::~String()2 {3     if(--pStringValue->refCount == 0)4     {5         delete pStringValue;6     }    7 }

8、Copy-On-Write(写时才复制)

考虑s1,s2指向同一个内容,s1[2] = f; 程序员期望只是修改s1,如何支持?

1 char& operator[](int index) 2 { 3     if(this->pStringValue->refCount > 1) //存在其他人共享 4     { 5         --this->pStringValue->refCount; 6         this->pStringValue = new StringValue(pStringValue->pData); 7     } 8      9     return pStringValue->pData[index];10 }

9、考虑 char* pc = &s1[2]; 然后修改pc,还是会修改s2,怎么办?

  增加一个标志位,访问[],设置StringValue不是共享。

10、现在假如Person,Book也有这种需求,怎么办?

  需要建立PersonValue,BookValue,通过建立基类,复用代码。RCValue为基类,RCValue 的copy构造和copy赋值,不需要做任何事,因为不会对RCValue调用copy构造和copy赋值。而是对String,Person,Book调用copy构造,copy赋值,传递pValue指针。

11、对于String中的pStringValue使用smart point,可以实现自动操作引用计数。

转载地址:http://oidpa.baihongyu.com/

你可能感兴趣的文章
CentOS 6.7下nginx SSL证书部署的方法分享
查看>>
菜鸟学SQLServer--数据文件和日志文件
查看>>
分享我积攒的测试相关的资料收集awesome-test
查看>>
1.2、solidworks入门1(零件建模、装配设计、工程图设计)
查看>>
SpringBoot Docker Mysql安装,Docker安装Mysql
查看>>
td中使用overflow:hidden; 无效解决方案
查看>>
Apache Flume 1.7.0 自定义输入输出
查看>>
第十周作业
查看>>
触摸事件基本介绍
查看>>
navigator.userAgent.indexOf来判断浏览器类型
查看>>
HDU 1556 Color the ball(树状数组)
查看>>
POJ 2456 Aggressive cows (二分)
查看>>
跳台阶的算法-python
查看>>
innodb_flush_method参数解析
查看>>
蛋白质结构模型和功能预测:Swiss-model工具的使用
查看>>
plink提取指定样本和指定SNP的数据(keep,extract函数)
查看>>
python算法
查看>>
多维数组的遍历性能
查看>>
CSS选择器
查看>>
服务器的操作系统和我们用的操作系统有什么区别? (转)
查看>>