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,這里就寫一點思路,具體代碼就略過了。

        

 

        

        

        

               

 

 

         


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM