個人部落格傳送門
智慧型指標是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()
建立模型如下:
根據上面例子,_next
和next
都指向後面節點這個空間,next._refcount = 2
。_prev
和cur
指向前面那個節點的空間,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 = 1
,cur._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 中,...