c++提供了4種智慧型指標用於對分配的記憶體進行自動釋放,分別如下
auto_ptr、unique_ptr、shared_ptr、weak_ptr。其中auto_ptr在c++98標準引入,後三種在c++11標準中加入。
說到智慧型指標就不能不提 raii
raii:即是定義乙個類來封裝資源的分配和釋放,利用建構函式實現資源的分配和初始化,利用析構函式完成資源的清理,可以保證資源的正確利用,避免記憶體洩漏。而智慧型指標只是raii的一種應用。
智慧型指標的簡介
c++智慧型指標是行為類似於指標的類物件。它使用設計模式中的**模式,**了原始「裸」指標的行為,為指標新增了更多更有用的特性。
c++引入異常機制後,智慧型指標由一種技巧公升級為一種非常重要的技術,因為如果沒有智慧型指標,程式設計師必須保證new物件能在正確的時機delete,四處編寫異常捕獲**釋放資源,而智慧型指標則可以在退出作用域時——不管是正常離開或是因異常離開——總呼叫delete來析構在堆疊上動態分配的物件。
因為c++異常處理的真正功能在於它具有為異常拋擲前構造的所有區域性物件(那麼智慧型指標物件也適用)自動呼叫析構函式的能力(c++異常機制不僅僅在於它能夠處理各種不同型別的異常)。所以在異常退出智慧型指標物件作用域時,總能由c++異常機制呼叫析構函式釋放在堆疊上動態分配的物件。
當然,正常退出物件(智慧型指標物件也屬於此列)作用域也會自動呼叫析構函式釋放在堆疊上動態分配的物件。
由此可知,將「裸」指標包裝成智慧型指標物件可以實現動態分配的記憶體物件的自動釋放。
而且c++智慧型指標物件可以像原指標那樣直接使用運算子,如賦值運算子'=',指標運算子'->',解引用運算子『*』。
智慧型指標的特點
1.智慧型指標管理的是一塊記憶體的釋放。
2.智慧型指標是乙個類,有類似指標的功能。
智慧型指標 auto_ptr的模擬實現
首先當auto_ptr的成員變數主要有t* _ptr, bool _owner時, 主要實現原理是在構造物件時賦予其管理空間的所有權,_owner賦值為true,在析構函式中通過_owner的真假來決定是否釋放空間,並且在拷貝或賦值後通過將_owner設為false,轉移空間的所有權。但是此做法存在乙個致命的問題,如果拷貝出來的物件出了作用域釋放了,雖然原來的物件的_owner仍為false,但通過解引用可能會訪問一塊已經釋放的一塊空間。
改進的版本還是將空間的管理權轉移,但實現方法中沒有_owner。拷貝和賦值後直接將_ptr賦值為空,不可能再訪問原來的記憶體空間。
通過實現和了解auto_ptr,我們知道了智慧型指標的由來和用法,但是通過深入了解,我們又知道auto_ptr 存在很大的缺陷,在拷貝構造的時候兩個指標指向同一塊記憶體釋放會出現問題,就像我們上邊圖示的那樣。
所以就引出了後來的幾種用法;
scoped_ptr,是首先為了解決auto_ptr引出的一種簡單粗暴的方法,就是防止他拷貝,這樣就不存在釋放時的記憶體洩漏問題,但是同樣也存在很大的缺陷,就是他功能上有缺失,但是這個好就好在簡單方便。下來我們來實現一下
templateclass scopedptr
t* operator->()
t operator*()
~scopedptr()
protected:
scopedptr& operator=(const scopedptr& s);
scopedptr(scopedptr& ap);
private:
t* _ptr;
};void test()
int main()
scopedptr中對拷貝建構函式和賦值運算子的過載函式只是進行了宣告,並沒有去定義這兩個函式,而且宣告為protected或者是private,這是防止別人在類外對這兩個函式進行定義。防止拷貝,所以說scopedptr是一種簡單粗暴的方式。
這裡要說的是有的人會搞混unique_ptr 和scaoped_ptr,其實最先是c++98庫出的auto_ptr,但是由於存在缺陷,然後就有各路大神們建了乙個叫做boost的庫,並陸續開發了scoped_ptr,和shared_ptr(我們後邊會實現),然後獲得了很多人的認可,到了c++11的時候就借鑑了這種實現,同時在對scoped_ptr做了改進之後命名為unique_ptr。
1.auto_ptr 管理權的轉移,帶有缺陷的設計 (c++98)
2.scoped_ptr(boost) unique_ptr(c++11) 防拷貝 (簡單粗暴的設計,功能缺陷)
3.shared_ptr(boost/c++11) 利用引用計數,是比較完美的智慧型指標,同時也很複雜,(支援拷貝,支援定製刪除器) 缺陷是會在有的情況下產生迴圈引用問題(採用weak_ptr配合解決)
智慧型指標類模板(上) STL中的智慧型指標
智慧型指標類模板 智慧型指標本質上就是乙個物件,它可以像原生指標那樣來使用。智慧型指標的意義 現代c 開發庫中最重要的類模板之一 c 中自動記憶體管理的主要手段 能夠在很大程度上避開記憶體相關的問題 1.記憶體洩露,在測試階段很難發現。造成的原因就是申請堆空間中的記憶體,忘記釋放。2.多次指標釋放 ...
C 中的智慧型指標
長久以來 c 最被人詬病的就是它的記憶體管理,寫個稍微複雜點的程式就經常會碰到記憶體洩漏問題。為了解決這個問題,c 也做了許多努力。在 c 98 標準中首先提出了智慧型指標的概念,引入了 auto ptr。但是在實踐中,auto ptr 有不少問題。因此在 c 11 標準中對原有的智慧型指標又做了進...
c 中的智慧型指標
1.智慧型指標的作用 為了防止記憶體洩露的問題 c 程式設計中使用堆記憶體是非常頻繁的操作,堆記憶體的申請和釋放都由程式設計師自己管理。程式設計師自己管理堆記憶體可以提高了程式的效率,但是整體來說堆記憶體的管理是麻煩的,c 11中引入了智慧型指標的概念,方便管理堆記憶體。使用普通指標,容易造成堆記憶...