c++引用计数的本质

以后会多写些本质论的文章,这样可以更好的引导自己去深入思考。

为什么要用引用计数?

场景:代码里X是一个非常重要的资源,模块A,B,C都有对其指针的引用,那么为了不出现内存泄露,常规的代码我们要怎么写?

  1. A 模块用完X时,需要检查B,C是否还在引用X,如果B,C有一个在用,那么X只要删除掉对A的引用就可以了,

如果B,C对A都已经没有引用了,那么A需要删除对X的引用时,要同时清除掉X。

2.同样B,C在用完X时,也要重复做1里面的事情。

这样,代码将会多了许多的逻辑判断,同时模块B,C还需要对模块A提供查询是否在引用X的接口。

可以不这么恶心吗?

思考:能否A在释放X前,不需要知道是谁在引用X,只要知道有多少人在引用X?

回答:是的,如果只有我用X,那么我就直接删除,如果还有其他人用,我就什么都不管,只要去除掉对X的引用就可以了。 情况就会变的好一些。

那么如何做到能知道资源的引用次数那?

这就需要对每一个资源X的都有一个的计数,这个计数是和资源X的生命周期息息相关的。

那么如何来管理这个计数?怎么能在有模块引用资源X的时候,计数++,模块释放资源X的时候计数--那?

这个就有一定难度了,引用的方式会有很多种,比如 A = X; A.push_back(X); A[100] = X; ...

当然我们可以在代码里的每一处增加和释放资源引用的地方,都加上代码count++,count--;但这亦然很麻烦,维护成本很高。

如何简单些?

能否把对资源的引用和释放,看成是对一个类的拷贝和销毁来完成? 弄一个代理类,里面封装好计数和资源X。

把所有对资源X的引用都理解成对代理类的引用,对代理类的引用都理解成对代理类的拷贝,对代理的释放就是销毁代理类。

这样我们只需要在代理类的拷贝函数里count++ , 代理类的析构做count--就好了。

如果代理类的资源引用计数count 减为0,就看成所有人都释放了对资源X的引用,这时由代理类来完成对资源的销毁。

这样下来,事情就简化了很多。 所以学会抽象是多么重要的一件事情。

一点code:

class RefPtr
{
     size count;
     X * ptr;    
}
class Proxy
{
       RefPtr* ptr;    
};

1 Proxy里面需要重载=, 拷贝构造

2 Proxy需要提供访问ptr的接口

3 Proxy需要在拷贝的地方增加计数,析构的时候判断是否删除ptr

--- ko,这里就写一点思路,具体代码就略过了。

原文链接: https://www.cnblogs.com/simplemind/archive/2013/01/19/2868179.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/76081

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午5:20
下一篇 2023年2月9日 下午5:20

相关推荐