C 11 STL智慧型指標的基本使用

2021-09-19 05:47:51 字數 3811 閱讀 4529

在c++中解決記憶體洩漏的有效方法是使用智慧型指標(smart pointer)。智慧型指標和普通指標的用法類似,只是不需要手動釋放記憶體,而是通過智慧型指標自己管理記憶體釋放。

智慧型指標是儲存指向動態分配(堆)物件指標的類,用於生存期控制,能夠確保在離開指標所在作用域時,自動正確的銷毀動態分配的物件,防止記憶體洩漏。它的一種通用

實現技術是使用引用計數,每使用它一次,內部的引用計數加1,每析構一次,內部引用計數減1,減為0時,刪除所指向的堆記憶體。

c++11 提供了3種智慧型指標:std::shared_ptr、std::uniq_ptr、std::weak_ptr,標頭檔案為

一、shared_ptr 共享的智慧型指標:

一:初始化:

通過 建構函式、std::make_shared輔助函式、reset方法來初始化shared_ptr,優先使用make_shared來構造智慧型指標

std::shared_ptrp(new int(1));

std::shared_ptrp2=p;

std::shared_ptrptr;

ptr.reset(new int(1));

對於乙個未初始化的智慧型指標,可以通過reset方法來初始化。

當智慧型指標中有值的時候,呼叫reset會使引用計數減1,

通過過載bool型別操作符來判斷智慧型指標中是否為空

獲取原始指標:當需要獲取原始指標時,可以通過get方法來返回原始指標

std::shared_ptrptr(new int(1));

int *p=ptr.get();

二:刪除共享指標

(1)刪除指標:

(1)指定刪除器:當p的引用計數為0時,自動呼叫刪除器deleteintptr 來釋放物件的記憶體

void deleteintptr(int* p)

std::shared_ptrp(new int,deleteintptr); //當p的引用計數為0了,就銷毀p

(2)lambda表示式也可以    

std::shared_ptrp(new int,(int *p));

(2)刪除陣列指標

(1)shared_ptr管理動態陣列時,需要強制指定刪除器,預設的刪除器不支援陣列刪除指標。

std::shared_ptrp(new int[10],(int *p));

(2)void deleteintptr(int* p)

(3)std::shared_ptrp(new int,deleteintptr); //當p的引用計數為0了,就銷毀p

(4)也可以將std::default_delete 作為刪除器。default_delete的內部是通過呼叫delete來實現功能的:推薦

std::shared_ptrp(new int[10],std::default_delete);

注意:(1) 不能將乙個原始指標直接賦值給乙個智慧型指標

std::shared_ptrp=new int(1);//編譯報錯,不允許直接賦值

(2) 不要用乙個原始指標初始化多個shared_ptr,例如下面這些事錯誤的

int *ptr=new int;

shared_ptrp1(ptr);

shared_ptrp2(ptr);//logic error

(3) 不要在函式實參中建立shared_ptr

function (shared_ptr(new int),g());//有缺陷

正確的寫法應該是先建立智慧型指標:    shared_ptrp(new int());   f(p,g());

(4) 通過shared_from_this()返回this指標。不要將this指標作為shared_ptr返回出來,因為this指標本質上是乙個裸指標,因此,這樣可能會導致重複析構。

shared_ptrgetself()

正確做法:讓目標類通過派生std::enable_shared_from_this類,然後使用基類的成員函式shared_from_this來返回shared_ptr

class a:public std::enable_shared_from_this

};std::shared_ptrspy(new a);

std::shared_ptrp=spy->getself();  //正確

(5) 要避免迴圈引用。智慧型指標最大的乙個陷阱是迴圈引用,迴圈引用會導致記憶體洩露:

class a

}//解決方式,在類a、類b中生命的shared_ptr指標有乙個為弱引用指標weak_ptr ,即可解決問題 

二、unique_ptr 獨佔的智慧型指標

unique_ptr是乙個獨佔型的智慧型指標,它不允許其他智慧型指標共享其內部的指標.

1、初始化  

(1)不允許通過賦值將乙個unique_ptr賦值給另外乙個unique_ptr。

unique_ptrmyptr(new t);

unique_ptrmyotherptr=myptr;//錯誤!! 不能複製

(2)unique_ptr不允許複製,可以通過函式返回給其他的unique_ptr,可以通過std::move來轉移到其他的unique_ptr,之後它就不在擁有原來指標的所有權.

unique_ptrmyptr(new t); //ok

unique_ptrmyotherptr=std::move(myptr);//ok

(3)unique_ptr除了獨占性這個特點之外,還可以指向乙個陣列

std::unique_ptrptr(new int[10]);

ptr[9]=9;//設定最後乙個元素為9

2、刪除指標,指定刪除器

(1)std::unique_ptr指定刪除器的時候需要確定刪除器的型別

std::unique_ptr> ptr(new int(1),[&](int* p));

(2)自定義unique_ptr的刪除器

void deleter(connection *connection)

unique_ptrup(new connection("unique_ptr"), deleter);

另一種使用方法:

class cconnnect

};class deleter

};std::unique_ptrup2(new cconnnect, up1.get_deleter());

三、weak_ptr 弱引用的智慧型指標

弱引用指標weak_ptr是用來監視shared_ptr的,不會使引用計數加1,它不管理shared_ptr內部的指標,主要是為了監視shared_ptr的生命週期,

更像是shared_ptr的乙個助手

(1)初始化:

1:通過use_count()方法來獲得當前觀測資源的引用計數.

shared_ptrsp(new int(10));

weak_ptrwp(sp);

coutweak_ptrwp(sp);

if(wp.expired())

f();

}//輸出:42  gw is expired

4:weak_ptr返回this指標

提到不能直接將this指標返回為shared_ptr,需要通過派生std::enable_shared_from_this類,

並通過其他方法shared_form_this來返回智慧型指標,因為std::enable_shared_from_this類中有乙個weak_ptr,這個weak_ptr用來觀測this智慧型指標,

呼叫shared_from_this()方法時,會呼叫內部這個weak_ptr的lock方法,將所觀測的shared_ptr返回.

5:weak_ptr 解決迴圈引用問題

class a

}(3)

(4)(5)

C 11 STL中的容器

一 順序容器 vector 可變大小陣列 deque 雙端佇列 list 雙向鍊錶 forward list 單向鍊錶 array 固定大小陣列 string 與vector相似的容器,但專門用於儲存字元。二 關聯容器 按關鍵字有序儲存元素 底層實現為紅黑樹 map 關聯陣列 儲存關鍵字 值對 se...

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...