2010-03-08 49 views
13

由于遗留原因,我需要使用入侵指针,因为我需要将原始指针转换为智能指针的能力。有没有boost :: weak_intrusive_pointer?

但是我注意到没有微弱的侵入指针来提升。我确实在boost线程列表上找到了一个关于它的讨论,但没有具体的。

有谁知道弱介入指针的线程安全实现?

由于 富

回答

10

这没有任何意义。

详细说明:weak_ptr指向shared_ptr所做的同一个counter对象实例。当shared_ptr超出范围时,counter的实例停留(有效计数为0),这允许weak_ptr实例检查它们是否有效地指向释放的对象。

使用侵入计数,计数器集成在对象内。当计数达到0时,该对象通常会被回收或删除...但点是计数器不再可用。理由是这允许更高效的存储(1个单块)和更高的速度(缓存局部性)。

如果您需要弱引用计数并且不关心侵入计数的好处,则可以使用shared_ptrweak_ptr的组合。

这个想法是从对象中取消关联计数器。

class Counted 
{ 
    // bla 
private: 
    boost::shared_ptr<int> mCounter; 
}; 

现在你可以返回弱手柄:

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; 
}; 

在这里,我们deassociate从对象的生命周期计数器的寿命,使之生存的对象的破坏......部分。从而有效地使weak_ptr成为可能。

当然,并使用shared_ptrweak_ptr这是线程安全的;)

+0

我的想法是将共享ptr和弱ptr使用的共享对象嵌入到主机对象中,并且intrusive_weak_ptr(如果存在的话)将以与weak_ptr相同的方式使用它。当没有更多的引用时,我仍然需要删除对象的功能。另外我需要弱引用。 – Rich 2010-03-08 13:46:18

+0

我认为你不明白我的观点:那正是我所提议的。 “计数”对象是“入侵式”计数的,我只是将计数器从普通整数更改为指向整数的指针。至于你的'intrusive_weak_ptr'这就是我所说的'WeakHandle'。 – 2010-03-08 15:00:30

+0

啊,我想我和你在一起。所以我会像普通一样使用一个入侵指针,但是当intrusive_ptr_add_ref被调用时,我从共享指针引用int作为我的计数。当它达到零时,对象被释放,但是任何弱引用都维持一个指向int的指针。那是对的吗? – Rich 2010-03-08 15:11:19

4

当前实现侵入指针的是使用参考计数器。所以删除对象删除也会删除计数器,所以weak_intrusive_pointer永远不会知道该对象已被删除。

如果您需要从this获得weak_ptr,那么您可能搜索了boost::enable_shared_from_this<T>

3

我真的不喜欢无论是以前的答案如此的:

不,我不知道实现的,但我认为这是可能的。 shared_ptr的标准实现包含两个引用计数,一个用于“强”,一个用于“弱”引用,以及指向所指对象的指针。在intrusive_ptr实现中,强计数需要成为对象的一部分,但弱是不可能的。所以,你似乎可以创建一个“可以弱化”的intrusive_ptr。

定义弱指针助手:

template<class X> 
class intrusive_ptr_weak_helper { 
    long weak_ref_count; 
    X *target_instance; 
}; 

然后录制到所述参考计数旁边的对象:

struct X { 
    ... 
    intrusive_ptr_weak_helper *ref_weak_helper; 
    ... 
    long ref_count; 
    ... 
}; 

构建当X:

ref_count = 0; 
ref_weak_helper = NULL; 

“强”指针intrusive_strong_ptr与intrusive_ptr相同,直到发生删除。当强ref计数变为零(删除发生前):

if (ref_weak_helper != NULL) { 
    if (ref_weak_helper->weak_ref_count == 0) 
     delete ref_weak_helper; 
    else 
     ref_weak_helper->target_instance = NULL; 
} 

“弱”的版本,intrusive_weak_ptr,记录了指针弱帮手,操纵该参考计数,并经由target_instance访问目标对象指针。当weak_ref_count递减为零时,target_instance的状态决定是否删除帮助器。

有许多细节丢失(例如并发问题),但是这是shared_ptr和intrusive_ptr的混合。它保持intrusive_ptr(缓存优化,第三方入侵(强)引用计数的重用,强和弱指针替代指针大小)的基本好处,同时主要在弱引用路径中添加额外的工作。

相关问题