c++智能指針

前言:C++中的智能指針有效解決了c++內存管理的問題。

1.背景(緣由)

在c++中,內存管理一直是對於程序員來講的一個噩夢。通常存在以下3種情況,

1)忘記delete,造成內存泄露;

2)指針指向的內存被釋放後(delete),造成指針成爲野指針(懸掛指針)。這種情況若再次使用指針會造成未定義或非法內存的錯誤。

3)重複delete。

對於智能指針,可以有效解決上述的三個問題。

2.定義

智能指針是管理動態分配內存的類,藉助引用計數技術,用於生存期控制,智能地在合適的時間完成析構的調用或動態內存的釋放。

3.結構

在智能指針類中,包含原始指針和引用計數,以及對->和*運算符的重載。在實現引用計數中,可以使用輔助類和句柄類。以下是輔助類的定義,轉自點擊打開鏈接

<pre name="code" class="cpp">class U_Ptr
{
    friend class HasPtr;
    int *ip;
    size_t use;
    U_Ptr(int *p) : ip(p) , use(1)
    {
        cout << "U_ptr constructor called !" << endl;
    }
    ~U_Ptr()
    {
        delete ip;
        cout << "U_ptr distructor called !" << endl;
    }
};


智能指針類,封裝了U_Ptr類。

4.規則

1)每當創建智能指針時,將指針的引用計數初始化爲1;

2)當對象賦值過程中,左邊的對象引用計數減1,右邊的對象引用計數加1;

3)當對象作爲另一個對象副本創建時,複製指針並將相應引用計數加1。

4)當引用計數變爲0時,調用析構函數或delete釋放內存。

5.智能指針舉例

點擊打開鏈接

由於 auto_ptr 基於【排他所有權模式】,這意味着:兩個指針(同類型)不能指向同一個資源,複製或賦值都會改變資源的所有權。

新加入標準模板庫(STL)的智能指針有兩個:

shared_ptr:基於引用計數模型。每次有 shared_ptr 對象指向資源,引用計數器就加1;當有 shared_ptr 對象析構時,計數器減1;當計數器值爲0時,被指向的資源將會被釋放掉。且該類型的指針可複製和可賦值,即其可用於STL容器中。此外,shared_ptr 指針可與多態類型和不完全類型一起使用。主要缺點:無法檢測出循環引用(後面會細說),如一顆樹,其中既有指向孩子結點的指針又有指向父親結點的指針,即孩子父親相互引用。這會造成資源無法釋放,從而導致內存泄露。爲了 fix 這個問題,引入了另一個智能指針:weak_ptr.

weak_ptr:指向有shared_ptr 指向的資源(即其需要shared_ptr的參與,其輔助 shared_ptr 之用),但是不會導致計數。一旦計數器爲0,不管此時指向資源的 weak_ptr 指針有多少,資源都會被釋放,而所有的這些 weak_ptr 指針會被標記爲無效狀態(即 weak_ptr作爲觀察shared_ptr 的角色存在着,shared_ptr 不會感受到 weak_ptr 的存在)。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章