智慧型指標 實現shared ptr

2021-09-25 09:17:02 字數 2311 閱讀 4459

前面介紹的auto_ptr和unique_ptr都存在著些許的缺陷,顯得不是那麼的「智慧型」,下面我們來看一下較為智慧型的shared_ptr的設計思路(一塊空間、計數器、鎖):

與前兩者不同的是shared_ptr用乙個count的引用計數將指向同乙份記憶體空間的指標,用_count來表示,這樣在析構的時候,會判斷_count是否為0,再決定是否示釋放空間:

但是並不僅僅是乙個_count就能解決的問題,在遇到多執行緒程式設計的時候,_count就變成了共享資源,而對_count的操作也就需要多留心一下,為了保證對_count的操作是安全可靠的,所以就引入了mutex

#include #include using std::mutex;

using std::cout;

using std::endl;

template class shared_ptr

~shared_ptr()

shared_ptr(const shared_ptr& p)

:_ptr(p._ptr)

, _pcount(p._pcount)

, _pmutex(p._pmutex)

shared_ptr& operator=(const shared_ptr& p)

return *this;

} t& operator*()

t* operator->()

int addcount()

int subcount()

int getcount()

private:

void realase() }

private:

t* _ptr;

int* _pcount;

std::mutex* _pmutex;

};

以下是我的測試用例:

下圖是第乙個斷點之後的內容:

下圖是第二個斷點之後的內容

之前提過的shared_ptr會有乙個迴圈引用的缺點,會造成不能正常析構的問題:

#include class bb;

class aa

~aa()

shared_ptrm_bb_ptr; //因為bb還未定義,所以在之前先宣告一下

};class bb

~bb()

shared_ptrm_aa_ptr; //!

};int main()

在ptr_a和ptr_b物件中的shared_ptr的沒有互相引用之前:ptr_a中有m_bb_ptr,而m_bb_ptr中又有m_aa_ptr就截止了。

在相互連線起來之後:就會無限的迴圈引用下去,這樣兩個shared_ptr指標相互保管,誰都不回先釋放。所以不能執行析構函式,實際上兩個物件ptr_a和ptr_b所指向的資源都只有乙個指標指向,而兩個物件中的成員都指向了另乙個物件。所以造成了歧義,這樣不會呼叫析構函式,造成記憶體洩漏。

將兩個類中的成員型別定義為weak_ptr就可以解決這個問題,因為weak_ptr , 它的構造和析構不會引起引用記數的增加或減少

這是因為weak_ptr是一種不控制所指向物件生存期的智慧型指標,它指向由乙個shared_ptr管理的物件。將乙個weak_ptr繫結到shared_ptr不會改變shared_ptr的引用計數。一旦最後乙個指向物件的shared_ptr被銷毀,物件就會被釋放。即使weak_ptr指向物件,物件也會被釋放。

將aa類和bb類中的成員定義為weak_ptr我們就可以達到正常的邏輯了: 能夠正常的析構

shared ptr智慧型指標

智慧型指標是乙個行為類似指標的物件。我們在使用堆記憶體時,都需要及時地進行釋放,避免造成記憶體洩漏。但我們偶爾也會忘記將其釋放掉,從而造成記憶體洩漏。並且,在釋放的時候,我們可能對某乙個指標進行了重複釋放,導致程式崩潰的問題。為了能夠解決這些問題,從而有了智慧型指標的設計。智慧型指標一共有四種,分別...

shared ptr(智慧型指標)

只要將 new 運算子返回的指標 p 交給乙個 shared ptr 物件 託管 就不必擔心在 寫delete p語句 實際上根本不需要編寫這條語句,託管 p 的 shared ptr 物件在消亡時會自動執行delete p。而且,該 shared ptr 物件能像指標 p 樣使用,即假設託管 p ...

智慧型指標shared ptr

shared ptr在脫離自己的作用域時候,會自動呼叫析構函式。作用域包含 塊 被呼叫函式 main函式等。include include include include using namespace std class a a int n private int n string str voi...