《Effective Modern C++》item 20:std::weak_ptr

                                                  採取行動乃消除焦慮的最好辦法之一。


Use std::weak_ptr for std::shared_ptr like pointers that can dangle.
 


 關於shared_ptr:  https://blog.csdn.net/qq_35865125/article/details/103865618

關於shared_ptr和weak_ptr的實現:https://blog.csdn.net/qq_35865125/article/details/88918909


-------weak_ptr是shared_ptr的補充,其指向一個資源,但是不會影響該資源的引用計數, weak_ptr指向已經被

shared_ptr託管的資源,很重要的一個用處是檢查該資源是否已經被銷燬:

-------weak_ptr一般通過shared_ptr進行初始化,即指向已經被shared_ptr託管的對象,當shared_ptr託管的這個對象

被銷燬侯,weak_ptr會變爲野指針, 但是,weak_ptr沒有提供解引用的操作。對於weak_ptr來說,可以調用其expired

函數檢查其指向的資源是否已被銷燬,但是以下這種操作不存在:
if(非expired)  {通過weak_ptr對指向的對象進行操作}, 因爲weak_ptr沒有提供解引用的方法,這樣也有利於安全,例如,調用expired

函數時非空,但是下一刻空了,則導致對指向的對象進行操作將會產生混亂:

 

 

-----但是人們需要經常使用 if(非expired)  {通過weak_ptr對指向的對象進行操作} 這種邏輯,爲了實現這種,必須保證

判斷非expired和後面的解引用是automic操作, 一般情況下可以採用下面兩種方法:



----weak_ptr的使用經典使用案例(1):factory function with cached info (經常使用的一種工廠函數!)

在item 18講解unique_ptr時,講到了其一個使用案例,即一個工廠函數,用於生成類對象並返回, 當時建議將返回類型

設置爲unique_ptr,即讓調用該工廠函數的人負責對象的生命週期。 但是,有另一種常用的工廠函數,其入參中有一個

類型值,工廠需要根據該類型生成相應的對象並返回,而且,如果某類型的對象已經生成過了就不用在新生成一個了(單例),

這種情況下,需要在函數內部做緩存,例如使用map,來記錄已經生成了的那些類型的對象,這時,返回類型應該爲shared_ptr,

函數內部用於緩存的指針應該使用weak_ptr(當函數返回的shared_ptr在外部被銷燬時,裏面的weak_ptr可以知道其被銷燬了):

----上面的fastLoadWidget函數有一些缺點:例如當其返回的一種id對應的對象被銷燬以後,函數的map仍然保存着這個銷燬的對象的weak_ptr,可以優化,但是優化不設計weak_ptr的特性,這裏沒講了哦:

 

----weak_ptr的使用經典使用案例(2): 發佈者訂閱者模式

在該模式中,發佈者需要存儲一個訂閱者列表,用於向它們發送通知,其實,發佈者並不care訂閱者

的生命週期,所以可以在內部使用weak_ptr來存儲訂閱者 ( 訂閱者的生命週期由shared_ptr負責)-- 妙

 

----weak_ptr的使用經典使用案例(3): 防止shared_ptr之間的循環引用

----也不是所有的場合都需要使用weak_ptr來打破循環引用:

 

----shared_ptr與weak_ptr的進一步對比:

item 21 在此: https://blog.csdn.net/qq_35865125/article/details/103965670

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章