采取行动乃消除焦虑的最好办法之一。
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操作, 一般情况下可以采用下面两种方法: (lock函数被面试问到过!!)
----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之间的循环引用
(云计算phone面试遇到的:有两个class A和B,它们都有成员一个shared_ptr成员,现在定义两个对象bojA,ojbB, objB中的shared_ptr成员指向objA, objA中的成员指向objB,为什么用weak_ptr就可以打破循环引用?两个类中的shared_ptr成员都要改成weak_ptr吗?::
answer: 假设objA在程序中被shared_ptr pA托管,例如程序开始时,new一个objA,然后给pA托管;同理,有pB托管objB对象。 然后,objA中的成员由pB构造, ojbB中的成员由pA构造。 然后, pA, pB的生命周期结束了,例如,用户显示地调用pA=null,pB=null,这时objA和objB都不会被销毁, 因为两者的引用计数还是1,因为还有其他shared_ptr指向它们啊。
解决方法: 将B类中的shared_ptr改成weak_ptr, 这样的话,pA=nullptr时,ojbA的引用计数就是减少为零,从而删除,删除后ojbA中的指向objB的shared_ptr也就没了, 然后,再pB=nullptr时,objB就会被删除了。 -- 当时知道原理,没能讲得这么细!)
----也不是所有的场合都需要使用weak_ptr来打破循环引用:
----shared_ptr与weak_ptr的进一步对比:
item 21 在此: https://blog.csdn.net/qq_35865125/article/details/103965670