我們從之前對于auto_ptr和unique_ptr介紹可以的知:
已經消失的智能指標——auto_ptr:https://blog.csdn.net/qq_46423166/article/details/113764347
C++智能指標——unique_ptr:https://blog.csdn.net/qq_46423166/article/details/113777696
- auto_ptr有很多問題,比如指標之間可以互相賦值,移動之后一個為空的問題,現在已經被棄用
- 然后unique_ptr不能直接使用復制建構式,但是通過別的方法依然會出現兩個指標指向同一個地址的錯誤,因此也有問題,
此時就產生了第三種智能指標:
shared_ptr
這種指標和unique_ptr的主要區別就是,允許多個指標指向同一個物件,
一些相同的用法就不解釋了,這里主要解釋一些與shaerd_ptr單獨的用法:
1,首先介紹關于定義的make_shared函式:
這是最安全的分配和使用動態記憶體的方法,它動態分配一個物件并初始化,并且回傳次物件的shared_ptr,
定義方法:
shared_ptr<int> a = make_shared<int>();
shared_ptr<int> b = make_shared<int>(42);
shared_ptr<string> c = make_shared<string>(10,'9');
2,shared_ptr的拷貝和賦值
這種指標比較允許多個指標指向同一個物件的原因就是有一個叫做參考計數的東西,即每個shared_ptr關聯的一個計數器
shared_ptr<int> a = make_shared<int>();
auto b(a);
- 第二行運行結束后,a和b就指向了同一個物件,因此shared_ptr關聯的計數器就會遞增,
- 當a或者b被銷毀后,這個關聯的計數器就會遞減,
此時我們可以用新函式use_count()函式來顯示

如上圖所示:
- 紅色線表示剛初始化,因此計數器為1
- 綠色線表示a,b同時指向一個物件,因此計數器加一變為2
- 因為b是臨時物件,所以當test函式之后,b就被銷毀了,計數器遞減,又變為1
此時又引出了新的函式:unique();
表示如果計數器為1,則回傳true,否則回傳false,
3,shared_ptr自動銷毀所管理的物件和相關聯的記憶體
當指向一個物件的最后一個shared_ptr被銷毀時,他就會呼叫類的成員函式——解構式來完成銷毀作業;
解構式會遞減它指向的物件的參考計數,如果參考計數變為0,shared_ptr的解構式就會銷毀物件,并釋放它占的記憶體,
對于一塊記憶體,使用shared_ptr安全的原因就是:
shared_ptr類報這個只要有任何shared_ptr物件參考它,它就不會被釋放掉
但是如果將shared_ptr存放在一個容器中,隨后重排了容器,從而不需要某些元素,這種情況下要確保erase洗掉了那些不在需要的shared_ptr元素,
weak_ptr
這個是一個弱參考,不控制所指向物件生存期的智能指標,他指向一個shared_ptr管理的物件,
弱參考的意思就是:
- 將一個weak_ptr系結到一個shared_ptr不會改變參考計數,
- 最后一個指向物件的shared_ptr被銷毀,物件就會被釋放,即使有weak_ptr指向物件,物件也還是會被釋放,
定義:
auto a = make_shared<int>(10);
weak_ptr<int> b(a);
使用 cout << a.use_count() << endl;觀察結果為1,表示參考計數并沒有增加,
因為這里使用的是弱參考,所以如果使用weak_ptr的話,就需要提前判斷指向的shared_ptr是否存在,
此時使用 b.lock()結果為true,
關于weak_ptr的一些函式:
- b.reset() 將b置為空
- b.use_count() 與b共享物件的shared_ptr的數量,若數量為0,則回傳true,否則返會false,
- b.expired() 如果為true,則回傳一個空的shared_ptr;否則回傳一個指向b的物件的shared_ptr
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/259514.html
標籤:其他
