C 11之智慧型指標

2021-07-13 23:55:19 字數 2883 閱讀 9300

c++98提供了了智慧型指標auto_ptr,但c++11已將其摒棄,並提供了unique_ptr和shared_ptr。這三種智慧型指標模板都定義了類似指標的物件,可以將new獲得的位址賦給這種物件。當智慧型指標過期時,這些記憶體將自動被釋放。其基本用法如下:

#include #include #include class report

~report()

void comment() const

};int main()

return 0;

}

輸出:

object created!

using auto_ptr

object deleted!

object created!

using shared_ptr

object deleted!

object created!

using unique_ptr

object deleted!

我們可以將這三種智慧型指標分成兩類。

對於auto_ptr和unique_ptr,它們使用的策略是:對於特定的物件,只能有乙個智慧型指標可擁有它。若通過copy建構函式或copy assignment操作符複製智慧型指標,它們會變成null,而複製所得的指標將取得資源的唯一擁有權。這樣做的好處是防止當多個auto_ptr或者unique_ptr同時指向乙個物件時物件會被刪除一次以上。

而對於shared_ptr,它使用的策略是」引用計數「,例如,賦值時,計數將加1,而指標過期時,計數將減1。僅當最後乙個指標過期時,才呼叫delete。

c++11提倡我們使用unique_ptr,那麼unique_ptr為何優於auto_ptr呢?

考慮下面這段程式

#include #include #include using namespace std;

int main()

執行這段程式將直接崩潰。在語句#2中,p2接管string物件的所有權後,p1的所有權將被剝奪。前面說過,這是好事,可防止p1和p2的析構函式試圖刪除同乙個物件。但在語句#3中,我們又使用了p1,這是件壞事,因為p1不再指向有效的資料。

現在我們用unique_ptr替換auto_ptr來執行程式

#include #include #include using namespace std;

int main()

這次不同的是,程式在編譯期間便出錯了。編譯器認為語句#2非法,避免了p1不再指向有效資料的問題。因此,unique_ptr比auto_ptr更安全(編譯階段錯誤比潛在的程式崩潰更安全)。

但有時候,將乙個智慧型指標賦給另乙個並不會留下危險的懸掛指標。假設有如下函式定義:

unique_ptrdemo(const char *s)
並假設編寫了如下**:

unique_ptrps = demo("uniquely special");
demo()返回乙個臨時unique_ptr,然後ps接管了原本歸返回的unique_ptr所有的物件,而返回的unique_ptr被銷毀。這沒有問題,因為ps擁有了string物件的所有權。但這裡的另乙個好處是,demo()返回的臨時unique_ptr很快被銷毀,沒有機會使用它來訪問無效的資料。換句話說,沒有理由禁止這種賦值。

總之,程式試圖將乙個unique_ptr賦給另乙個時,如果源unique_ptr是個臨時右值,編譯器允許這樣做;如果源unique_ptr將存在一段時間,編譯器將禁止這樣做。

然而,unique_ptr如何能夠區分安全和不安全的用法呢?答案是它使用了c++11新增的移動建構函式和右值引用。

此外,unique_ptr有new和delete的版本,而auto_ptr和shared_ptr只有new和delete的版本。

#include #include #include using namespace std;

int main()

現在我們在程式中使用shared_ptr,程式正常執行。因為我們將p1複製給p2時,p1和p2都包含指向string物件的指標,當p1和p2都被析構時,才會呼叫string物件的delete函式。

shared_ptr還允許指定」刪除器「,這是乙個函式或函式物件,當引用次數為0時便被呼叫。刪除器對shared_ptr建構函式而言是可有可無的第二引數。例如:當我們需要自定義乙個資源管理類lock時,對於乙個mutex的互斥器物件,在構造時呼叫lock(),在析構時呼叫unlock()。為了防止lock物件的copying行為,我們考慮使用引用計數法,希望儲存有資源直到它的最後乙個使用者被銷毀。此時我們可以使用shared_ptr的刪除器。

class lock 

private:

shared_ptrmutexptr;

};

如果程式要使用多個指向同乙個物件的指標,應選擇shared_ptr。這樣的情況包括:有乙個指標陣列,並使用一些輔助指標來標識特定的元素,如最大的元素和最小的元素;兩個物件包含都指向第三個物件的指標;stl容器包含指標。很多stl演算法都支援複製和賦值操作,這些操作可用於shared_ptr,但不能用於unique_ptr(編譯器發出警告)和auto_ptr(行為不確定)。

如果程式不需要多個指向同乙個物件的指標,則可使用unqiue_ptr。如果函式使用new分配記憶體,並返回指向該記憶體的指標,將其返回型別宣告為unique_ptr是不錯的選擇。這樣,所有權將轉讓給接受返回值的unique_ptr,而該智慧型指標將負責呼叫delete。可將unique_ptr儲存到stl視窗中,只要不呼叫將乙個unique_ptr複製或賦給另乙個的方法或演算法(如sort())。

c 11之智慧型指標

由於在c 中我們可以動態分配記憶體,但有時候我們會忘記用 delete或free釋放記憶體,就會導致記憶體洩露。所以c 11提供了智慧型指標這種東西 本文參考了知乎某知乎友的 比如下面這兩種情況 1 記憶體洩漏 str1所指的資源沒有被釋放 2 多重釋放,引起程式崩潰 可能平時都寫在乙個檔案不會忘記...

C 11智慧型指標

本文介紹c 的四種智慧型指標,其中後三種是c 11新增加的,auto ptr已被棄用。要編譯c 11,需要安裝g 4.8 sudo add apt repository ppa ubuntu toolchain r test sudo apt get update sudo apt get inst...

c 11 智慧型指標

如果在程式中使用new從堆 自由儲存區 分配記憶體,等到不需要時,應使用delete將其釋放。c 引入了智慧型指標auto ptr,以幫助自動完成這個過程。c 11摒棄了auto ptr,並新增了三種智慧型指標 unique ptr,shared ptr,weak ptr。一.auto ptr,un...