採取行動乃消除焦慮的最好辦法之一。
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