智能指针里弱引用应该如何实现?(WeakReference/WeakPtr<T>)

弱引用(指针)指的是这样一个概念:引用不控制对象的生命周期,但是对象本身销毁后,弱引用能得到“通知”。


 WeakPtr的实现思路(概念上的):(WeakPtr 1)===> (引用结构 2) <==> (实际的对象 3)
当(实际的对象3)由于调用析构函数销毁自己时,可以清除(引用结构 2)里面的信息,这样(WeakPtr 1)就得到了null,相当于被通知到了

一种可能的实现:让WeakPtr作为一个全局WeakHashMap中的item成员,每当一个对象T创建时,即以对象的id(对于Java)或者其地址(对于C++)作为WeakHashMap作为key,同时hook住对象的析构函数,当对象销毁时,从这个WeakHashMap移除此item即可。这里的场景有点像日本公司职员上班时需要往墙上挂一个木牌代表他当前在办公室里一样。

但是这个实现感觉哪里不对劲:假设实际对象3销毁后,创建一个新的对象4,4恰巧重新维护了原来2<==>3的双向引用,这种情况下,WeakPtr 1会误认为对象3实际上未被销毁,可以把这种问题称之为“名字盗用”。
所以我真的感觉不对劲:WeakPtr到底是如何实现的?

嗯,想到了一种新的可能的WeakPtr实现:让WeakPtr<T>的弱引用对象形成一个循环链表,而T的成员数据中有一个WeakPtr<T>*成员,初始为空,当第一个指向对象T的WeakPtr<T>被创建时,此成员有赋值。
假设初始弱引用a1指向A对象,其后增加了一个新的弱引用a2,然后删除a1,此时A对象中的此WeakPtr<T>*成员应该指向a2。

嗯,有时间应该看看C++ 11标准库是weak_ptr到底是怎么实现的,好像它是与shared_ptr相互关联的。但是从基本概念上,应该不会脱出我之前想到的这2种思路吧。



更正:WeakPtr不是这么实现的,RefPtr需要(PtrPtr 1)===> (引用结构 2) <==> (实际的对象 3)这样的概念连接,并且2实际上由于WebKit的RefCountedBase基类模板,与3共用一块内存。


WeakPtr的实现恰恰相反:(WeakPtr 1)===>  (实际的对象3,这里最关键的trick是一个WeakPtrFactory工厂对象作为实际对象的最后一个成员<===>(弱引用结构2) 

(弱引用结构2) 实际上是每个原始对象仅关联一个堆上的new内存,里面保存的就是对象本身的地址。——也就是说,把对象本身的地址存储到此对象关联的另外一个独立的堆内存数据结构里。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值