C 知識點36 使用智慧型指標的注意事項(下)

2021-10-25 06:18:02 字數 1977 閱讀 3095

四、智慧型指標與容器

當把shared_ptr物件放入乙個容器中時,會呼叫shared_ptr的拷貝建構函式並且引用計數+1

因為用new test()初始化up時,需要將new test()隱式轉化為乙個unique_ptr物件,需要呼叫unique_ptr的建構函式,但是unique_ptr的建構函式是explicit,所以轉化失敗

將第三行**改為

unique_ptrup(new test());

編譯通過

此外,也不要使用new返回的普通指標給乙個智慧型指標賦值,道理同上

同理,如果乙個函式的返回值或者形參是乙個unique_ptr或shared_ptr,也不要使用new建立的物件作為返回值或者作為引數,道理相同

六、最好不要混合使用智慧型指標和普通指標

正式因為可以用new返回的內建指標來初始化智慧型指標,但是如果將new返回的指標繫結到乙個智慧型指標的臨時變數上,那麼,new的物件就會被無緣無故釋放,當再次訪問該物件,有可能就會訪問到乙個空懸指標

示例

void testfunc(shared_ptrsp)

在中提到,當把乙個shared_ptr物件放入乙個容器中時,shared_ptr物件的引用計數會+1,但是如果當把乙個shared_ptr的臨時物件放入乙個容器中,引用技術並不會增加,因為shared_ptr的臨時物件會自動釋放。所以當上述函式的執行結束後,v中的元素的引用技術減少為0,指向物件的記憶體會自動被**,不用手動delete,防止了記憶體洩漏

所以,綜合第五點和第六點,最好不要使用普通指標來初始化乙個智慧型指標,如果使用shared_ptr,請使用make_shared函式來初始化shared_ptr;如果使用unique_ptr,請使用make_unique函式來進行初始化

如果乙個容器中儲存了智慧型指標的物件,當想容器中新增元素時,請使用make_shared函式建立乙個臨時變數並將該臨時變數新增到容器中

七、不要使用get函式給別的智慧型指標初始化或者賦值

get函式從shared_ptr物件中返回指向物件的普通指標,用於向不能使用智慧型指標的程式傳遞乙個普通指標,但是get雖然返回乙個普通指標,但是不要delete該指標,因為指向的內容的生命週期由智慧型指標來決定。如果delete該指標,那麼智慧型指標的引用計數為0時,會再次delete,造成二次delete錯誤。

此外,也不要使用get函式給別的智慧型指標初始化或者賦值

示例int main(int argc, char const *ar**)

上述**實現了乙個單鏈表,並且建立了兩個節點,當主函式執行結束後,兩個智慧型指標的生命週期結束。呼叫了兩次建構函式,記憶體被正確釋放

現在,新增乙個pre成員,指向前乙個節點,實現乙個雙向鍊錶,情況如下

class node

void arrarydeleter(int *p)

void customdeleter()

如果用shared_ptr指向乙個陣列,那麼需要自定義刪除器,或者使用default_delete(),shared_ptr的自定義的刪除器可以不做為模板引數傳入,但是unique_ptr的自定義刪除器必須作為模板引數傳入,必須指明刪除器的型別。unique_ptr如果不指定刪除器,預設刪除器執行delete t

參考《c++ 標準庫》

《c++ primer》

C 知識點複習 智慧型指標分析

智慧型指標引入為了解決的問題 記憶體洩漏 示例 include include using namespace std class test intvalue test intmain return0 智慧型指標示例 include include using namespace std class...

C 知識點34 動態記憶體與智慧型指標

一 動態記憶體 動態記憶體所在的位置在堆區,由程式設計師手動分配並手動釋放,而不像棧記憶體由系統分配和自動釋放 c 通過new運算子為物件在堆上分配記憶體空間並返回該物件的位址,並用delete運算子銷毀物件並釋放物件所佔的動態記憶體,如果分配動態記憶體後沒有手動釋放會產生記憶體洩露 new乙個物件...

C 智慧型指標使用

由於 c 語言沒有自動記憶體 機制,程式設計師每次 new 出來的記憶體都要手動 delete。程式設計師忘記 delete,流程太複雜,最終導致沒有 delete,異常導致程式過早退出,沒有執行 delete 的情況並不罕見。std auto ptr boost scoped ptr boost ...