《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

发布了341 篇原创文章 · 获赞 87 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/qq_35865125/article/details/103916712