Mat*_* M. 11
它没有任何意义.
详细说明:weak_ptr指向相同的counter对象实例shared_ptr.当shared_ptr超出范围时,counter停留的实例(计数有效地为0),这允许weak_ptr实例检查它们是否有效地指向释放的对象.
通过Intrusive Counting,计数器集成在对象中.当计数达到0时,对象通常被回收或删除......但重点是计数器不再可用.基本原理是,这允许更高效的存储(1个单块)和更高的速度(缓存局部性).
如果您需要弱引用计数和不关心侵入计数的好处,你可以使用的组合shared_ptr和weak_ptr.
我们的想法是将计数器与对象分离.
class Counted
{
// bla
private:
boost::shared_ptr<int> mCounter;
};
Run Code Online (Sandbox Code Playgroud)
现在你可以返回弱句柄:
class WeakHandle
{
public:
explicit WeakHandle(Counted& c): mCounter(c.mCounter), mObject(&c) {}
bool expired() const { return mCounter.expired(); }
private:
boost::weak_ptr<int> mCounter;
Counted* mObject;
};
Run Code Online (Sandbox Code Playgroud)
在这里,我们将计数器的生命周期与对象的生命周期取消关联,这样它就可以在对象的破坏中幸存下来......部分地.从而使weak_ptr有效成为可能.
当然,使用shared_ptr和weak_ptr这是线程安全;)
我真的不喜欢上述任何一个答案,所以:
不,我不知道实现方式,但是我认为这是可能的。shared_ptr的标准实现包含两个引用计数,一个用于“强”引用,一个用于“弱”引用,以及一个指向引用的指针。在intrusive_ptr实现中,强计数需要成为对象的一部分,但弱计数不能成为对象的一部分。因此,似乎您可以创建一个“弱”的intrusive_ptr。
定义一个弱指针助手:
template<class X>
class intrusive_ptr_weak_helper {
long weak_ref_count;
X *target_instance;
};
Run Code Online (Sandbox Code Playgroud)
然后将其记录到引用计数旁边的对象中:
struct X {
...
intrusive_ptr_weak_helper *ref_weak_helper;
...
long ref_count;
...
};
Run Code Online (Sandbox Code Playgroud)
构造X时:
ref_count = 0;
ref_weak_helper = NULL;
Run Code Online (Sandbox Code Playgroud)
在删除发生之前,“强”指针intrusive_strong_ptr与intrusive_ptr相同。当强引用计数变为零时(在发生删除之前):
if (ref_weak_helper != NULL) {
if (ref_weak_helper->weak_ref_count == 0)
delete ref_weak_helper;
else
ref_weak_helper->target_instance = NULL;
}
Run Code Online (Sandbox Code Playgroud)
“弱”版本intrusive_weak_ptr记录指向弱帮助器的指针,操纵该引用计数,并通过target_instance指针访问目标对象。当weak_ref_count减为零时,target_instance的状态将确定是否删除帮助程序。
缺少许多细节(例如,并发性问题),但这是shared_ptr和intrusive_ptr的混合体。它保持了intrusive_ptr的基本优点(缓存优化,第三方介入式(强)引用计数的重用,强指针和弱指针替身都是指针大小),同时主要在弱引用路径中添加了额外的工作。