四種智慧型指標剖析

2021-08-15 19:43:11 字數 3146 閱讀 3015

個人部落格傳送門

智慧型指標是c++中乙個程式設計技巧。它保證記憶體的正確釋放,解決了記憶體洩漏的問題。有乙個思想叫做raii,raii指的是資源分配即初始化。我們通常會定義乙個類來封裝資源的分配和釋放,在建構函式中完成資源的分配和初始化,在析構函式中完成資源的清理。

在c++中,我們一般是使用new和delete來實現記憶體的初始化和釋放。正確的配對使用可以處理絕大部分問題,但是如果出現了執行流的跳轉,比如:語句中間出現了return,break,continue,goto,等關鍵字,我們的delete可能沒有執行,這樣就導致了記憶體沒有被釋放。又或者我們的語句出現了錯誤,丟擲異常導致程式結束,也有可能沒有執行delete語句。這些問題都導致了記憶體洩漏。智慧型指標的出現就是為了解決這些問題的。智慧型指標其實是乙個類,它可以自動的處理指標指向的動態資源的釋放。

發展歷程

auto_ptr

//模擬主要函式:

template

class autoptr

~autoptr()

t& operator*()

t* operator->()

autoptr(autoptr& ap)

autoptr& operator=(autoptr& ap)

return *this;

}};int main()

**如下:

任何時候我們都不使用auto_ptr,因為管理權的轉移是不符合我們正常指標的使用的,而且會引起程式崩潰,這個是不允許的。

最後,解釋一下,operator->()返回t*的原因:

//設定乙個類

struct student

//呼叫

autoptrsp = new student;

sp->num = 20;

sp->num等價於sp.operator->()sp.operaotr->()返回t*指標之後,編譯器自動將原式優化為_ptr->num,從而實現對元素的訪問。

scoped_ptr

防拷貝的智慧型指標,boost版本相當於c++11的unique_ptr

//模擬拷貝的主要函式:

template

class scopedptr;

scoped_ptr通過將拷貝建構函式和賦值運算子過載定義為私有,同時只宣告不定義,這樣可以保證該類不能被拷貝。這就簡單的解決了auto_ptr因為拷貝導致的管理權轉移問題。

shared_ptr

引用計數的智慧型指標,這個類除了有指標之外,再多開闢了乙個記憶體空間,用於存放計數。這種智慧型指標是實現的最好的,在boost庫中,實現起來很複雜,因為要考慮多執行緒等情況。

//模擬主要函式

template

class sharedptr

//析構

~sharedptr()

}//拷貝構造

sharedptr(sharedptr& sp)

//賦值運算子過載

sharedptr& operator=(const sharedptr& sp)

_ptr = sp._ptr;

_refcount = sp._refcount;

(*_refcount)++;

}return *this;

}//*過載

t& operator*()

//->過載

t* operator->()

};

這個實現,將是比較實用的。但是依然有乙個場景下,會出現問題。這個問題叫做迴圈引用,問題的根源是引用計數被迴圈使用,不能減為0,導致死迴圈。下面以雙向鍊錶作為例子:

//定義乙個鍊錶節點如下

struct listnode;

//呼叫這個節點,設定這樣乙個場景

int main()

建立模型如下:

根據上面例子,_nextnext都指向後面節點這個空間,next._refcount = 2_prevcur指向前面那個節點的空間,cur._refcount = 2。當程式結束的時候,next先被析構。若需要析構next就需要析構next._prev;要析構next._prev就需要析構cur;要析構cur就需要析構cur._next;要析構cur._next就需要析構next……這樣就造成了死迴圈。為了解決這個迴圈引用的問題,引入了弱指標weak_ptr。

weak_ptr

弱指標不單獨使用,它的存在就是為了解決使用shared_ptr造成的迴圈引用問題。

template

class weakptr

weakptr(const sharedptr& sp)

t& operator*()

t* operator->()

weakptr& operator=(const sharedptr& sp)

};//還需要修改一下兩處:

//1、修改listnode的結構

struct listnode;

//2、將weakptr定義為sharedptr的友元,因為weakptr中需要訪問sharedptr的私有成員

template

class sharedptr;

這樣,上面那個例子中,next._refcount = 1cur._refcount = 1,就不會出現迴圈引用的問題了。

stl的四種智慧型指標

第一種 std auto ptr auto ptr是所有權轉移的智慧型指標,也就是同一時刻只有乙個智慧型指標物件對原物件擁有所有權。第二種 std scoped ptr scoped ptr智慧型指標無法使用乙個物件建立另乙個物件,也無法採用賦值的形式。這無疑提公升了智慧型指標的安全性,但是又存在無...

C 四種智慧型指標詳解

c 裡面的四個智慧型指標 shared ptr,unique ptr,weak ptr,auto ptr其中前三個是c 11支援,並且最後乙個已經被11棄用。智慧型指標的使用 智慧型指標主要用於管理在堆上分配的記憶體,它將普通的指標封裝為乙個棧物件。當棧物件的生存週期結束後,會在析構函式中釋放掉申請...

智慧型指標剖析

c 中,動態記憶體的開闢需要使用者自己管理,在使用完成之後,必須由使用者自己來釋放空間,當然,大部分程式設計師都會說,我肯定會記得釋放的,然而,對於這個問題,我們還是防不勝防,一不小心就會造成記憶體洩露。在這樣的情況下,我們為何不把開闢的空間交給智慧型指標來管理呢?這樣即高效又不容易出問題。c 中,...