標籤:存在 智能指標 null 運行時 weak_ptr isp lex 使用 關係
1、C++98的智能指標
2、C++11的智能指標
智能指標本質是一個模板類
(1)三種智能指標
標頭檔 <memory>
unique_ptr 共用的智能指標
shared_ptr 獨佔的智能指標
weak_ptr 弱引用的智能指標
(2)explict關鍵字
C++11之後的智能指標的建構函式都有explict關鍵詞修飾,表明它不能被隱式的類型轉換。
shared_ptr<int> p1 = new int(1024);
//編譯不過,因為等號左邊是一個類對象,等號右邊是一個int*的指標,因為有explict修飾,所以它不能被隱式的轉換為shared_ptr<int>的類型
shared_ptr<int> p2(new int(1024)); //這種是直接採用了初始化的形式
shared_ptr<int> p3 = make_shared<int>(1024); //也可以用make_shared類
3、unique_ptr
持有對對象的專屬權,同一時刻只能有一個unique_ptr指向給定對象(通過禁止拷貝語義、只有移動語意來實現)。
unique_ptr指標本身的生命週期:從unique_ptr指標建立時開始,直到離開範圍。離開範圍時,若其指向對象,則將其所指對象銷毀(預設使用delete操作符,使用者可指定其他動作)。
unique_ptr指標與其所指對象的關係:在智能指標生命週期內,可以改變智能指標所指對象,如建立智能指標時通過建構函式指定、通過reset方法重新指定、通過release方法釋放所有權、通過移動語意轉移所有權。
(1)類內部重載了*運算子,可以像指標那樣訪問所分配的堆記憶體
(2)由於其獨佔性,不能與其他unique_ptr對象共用所指向的堆記憶體
(3)up1隻能通過move語義把記憶體指向的所有權給另一個對象up2,然後up1自己就失去所有權,此時程式運行中再訪問up1時會出錯。
(4)使用類成員reset可以釋放其指向的堆記憶體
up2釋放之後,再對up1調用reset不會發生執行階段錯誤
再對 *up2 訪問的時候發生執行階段錯誤
4、shared_ptr
shared_ptr多個指標指向相同的對象。shared_ptr類內部使用引用計數,每一個拷貝的shared_ptr類對象都指向相同的記憶體。每拷貝一次,內部的引用計數加1,每析構一次,內部的引用計數減1,減為0時,自動刪除所指向的堆記憶體。shared_ptr內部的引用計數是安全執行緒的,但是對象的讀取需要加鎖。
get函數擷取原始指標,注意不要用一個原始指標初始化多個shared_ptr,否則會造成二次釋放同一記憶體。
注意避免循環參考,shared_ptr的一個最大的陷阱是循環參考,迴圈,循環參考會導致堆記憶體無法正確釋放,導致記憶體流失。循環參考在weak_ptr中介紹。
(1)使用make_shared構造對象的區別
盡量使用 make_shared 和 make_unique(C++14才有),少用 new
make_shared 和 new 都是申請堆記憶體,make_shared 優點是效率高(申請記憶體次數少),避免記憶體流失,缺點是建構函式是保護或私人時,無法使用 make_shared,對象的記憶體可能無法及時回收。
方式1:
兩次記憶體申請
方式2:
一次記憶體申請
(2)拷貝和賦值
拷貝使得對象的引用計數增加1,賦值使得原對象引用計數減1,當計數為0時,自動釋放記憶體。後來指向的對象引用計數加1,指向後來的對象。
對比unique_ptr,把堆記憶體共用給其他對象sp2後,再訪問sp1不會發生執行階段錯誤,只是引用計數發生變化。
(3)對比unique_ptr,用reset釋放sp1,訪問sp2不會發生執行階段錯誤
5、weak_ptr
兩個作用:記錄對象是否存在,解決shared_ptr環形依賴問題
(1)記錄對象是否存在
weak_ptr的對象是用來指向shared_ptr對象指向的記憶體,通過它的成員lock函數用來判斷shared_ptr指向的資料記憶體是否還存在。
調用lock函數能夠返回一個有效shared_ptr指標(即shared_ptr指向的堆記憶體不是空的),如果引用計數為0,則返回null 指標nullptr。
(2)解決shared_ptr環形依賴問題
6、make_shared 的缺點
具體下面部落格有說明:
72886630
https://www.cnblogs.com/shengjianjun/p/3691928.html
參考部落格:https://www.cnblogs.com/wxquare/p/4759020.html
56773039
https://www.cnblogs.com/shengjianjun/p/3691928.html
C++11 智能指標