智慧型指標原理及實現(1)shared ptr

2021-09-08 01:14:35 字數 2248 閱讀 4813

c++沒有記憶體**機制,每次程式設計師new出來的物件需要手動delete,流程複雜時可能會漏掉delete,導致記憶體洩漏。於是c++引入智慧型指標,可用於動態資源管理,資源即物件的管理策略。

使用 raw pointer 管理動態記憶體時,經常會遇到這樣的問題:

下面的**解釋了,當乙個操作發生異常時,會導致delete不會被執行:

void func() 

在c++98中,為了寫出異常安全的**,**經常寫的很笨拙,如下:

void func() 

catch(...)

delete ptr;

}

使用智慧型指標能輕易寫出異常安全的**,因為當物件退出作用域時,智慧型指標將自動呼叫物件的析構函式,避免記憶體洩露。

智慧型指標主要有三種:shared_ptr,unique_ptr和weak_ptr。

shared_ptr

shared_ptr是最常用的智慧型指標(專案中我只用過shared_ptr)。shared_ptr採用了引用計數器,多個shared_ptr中的t *ptr指向同乙個記憶體區域(同乙個物件),並共同維護同乙個引用計數器。shared_ptr定義如下,記錄同乙個例項被引用的次數,當引用次數大於0時可用,等於0時釋放記憶體。

注意避免迴圈引用,shared_ptr的乙個最大的陷阱是迴圈引用,迴圈,迴圈引用會導致堆記憶體無法正確釋放,導致記憶體洩漏。迴圈引用在weak_ptr中介紹。

templeclass sharedptr ;
shared_ptr物件每次離開作用域時會自動呼叫析構函式,而析構函式並不像其他類的析構函式一樣,而是在釋放記憶體是先判斷引用計數器是否為0。等於0才做delete操作,否則只對引用計數器左減一操作。

~sharedptr()

}

接下來看一下建構函式,預設建構函式的引用計數器為0,ptr指向null:

sharedptr() : _ptr((t *)0), _refcount(0)

用普通指標初始化智慧型指標時,引用計數器初始化為1,這裡注意new int(1):

sharedptr(t *obj) : _ptr(obj), _refcount(new int(1))

//這裡無法防止迴圈引用,若我們用同乙個普通指標去初始化兩個shared_ptr,此時兩個ptr均指向同一片內

//存區域,但是引用計數器均為1,使用時需要注意。

拷貝建構函式需要注意,用乙個shared_ptr物件去初始化另乙個shared_ptr物件時,引用計數器加一,並指向同一片記憶體區域:

sharedptr(sharedptr &other) : _ptr(other._ptr), _refcount(&(++*other._refcount))

賦值運算子的過載

當用乙個shared_ptrother去給另乙個 shared_ptrsp賦值時,發生了兩件事情:

一、sp指標指向發生變化,不再指向之前的記憶體區域,所以賦值前原來的_refcount要自減

二、sp指標指向other.ptr,所以other的引用計數器_refcount要做++操作。

sharedptr &operator=(sharedptr &other)

_ptr = other._ptr;

_refcount = other._refcount;

return *this;

}

定**引用運算子,直接返回底層指標的引用:

t &operator*()

定義指標運算子->

t *operator->()

int main(int argc, const char * ar**)

為了讓測試結果更明顯,我在方法中加入了一些輸出,測試結果如下:

思考1、本文這種寫法不是執行緒安全的,是吧?

2、boost中的shared_ptr執行緒安全嗎?

智慧型指標原理及C 實現

智慧型指標是乙個類,在類的建構函式中傳入乙個普通指標,析構函式釋放指標。引入智慧型指標是為了更好的管理記憶體,防止記憶體洩漏等問題。實現方法 採用引用計數的方法。智慧型指標將乙個計數器與類指向的物件相關聯,引用計數跟蹤共有多少個類物件共享同一指標。其遵循以下規則 1 每次建立類的新物件時,初始化指標...

智慧型指標 二 shared ptr實現原理

前面講到auto ptr有個很大的缺陷就是所有權的轉移,就是乙個物件的記憶體塊只能被乙個智慧型指標物件所擁有.但我們有些時候希望共用那個記憶體塊.於是c 11標準中有了shared ptr這樣的智慧型指標,顧名思義,有個shared表明共享嘛.所以shared ptr型別的智慧型指標可以做為stl容...

智慧型指標實現

namespace smart smart count 增加引用計數,並返回計數值.intaddref 減少引用計數,並返回計數值.intrelease private 計數變數.intuse count 智慧型指標.template class t class smart ptr 構造空指標.ex...