是否有 boost::weak_intrusive_pointer?

发布于 2024-08-24 01:44:09 字数 147 浏览 10 评论 0原文

由于遗留原因,我需要使用侵入式指针,因为我需要能够将原始指针转换为智能指针。

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

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

谢谢 富有的

For legacy reasons I need to use intrusive pointers, as I need the ability to convert raw pointers to smart pointers.

However I noticed there is no weak intrusive pointer for boost. I did find a talk about it on the boost thread list, however nothing concrete.

Does anyone know of a thread safe implementation of weak intrusive pointer?

Thanks
Rich

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

菊凝晚露 2024-08-31 01:44:09

这没有任何意义。

详细说明一下: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;
};

在这里,我们将计数器的生命周期与对象的生命周期取消关联,以便它将在对象销毁后继续存在......部分。从而使 weak_ptr 有效地成为可能。

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

It does not make any sense.

To elaborate: weak_ptr points to the same instance of a counter object that shared_ptr do. When the shared_ptr goes out of scope, the instance of the counter stays (with a count effectively at 0), which allows the weak_ptr instances to check that they effectively point to a freed object.

With Intrusive Counting, the counter is integrated within the object. When the count reaches 0, the object is usually either recycled or deleted... but the point is the counter is no longer available. The rationale is that this allow for a more efficient storage (1 single chunk) and greater speed (cache locality).

If you need Weak Reference counting and do not care for the benefits of intrusive counting, you can use a combination of shared_ptr and weak_ptr.

The idea is to deassociate the counter from the objects.

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

Now you can return weak handles:

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

Here, we deassociate the lifetime of the counter from the lifetime of the object, so that it will survive the destruction of the object... partially. Thus making the weak_ptr effectively possible.

And of course, using shared_ptr and weak_ptr this is Thread Safe ;)

想挽留 2024-08-31 01:44:09

我不太喜欢前面的任何一个答案,所以:

不,我不知道实现,但我认为这是可能的。 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 相同,直到发生删除。当强引用计数变为零时(在删除发生之前):

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 的基本优点(缓存优化、重用第 3 方侵入式(强)引用计数、强指针和弱指针替代品都是指针大小),同时主要在弱引用路径中添加额外的工作。

I didn't really like either of the previous answers so:

No, I don't know of an implementation, but I think it is possible. The standard implementation of the shared_ptr holds two reference counts, one for the "strong" and one for the "weak" references, and a pointer to the referent. In an intrusive_ptr implementation the strong count needs to be part of the object, but the weak can't be. So, it seems like you could create a "weakable" intrusive_ptr.

Define a weak pointer helper:

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

Then record that into the object beside the reference count:

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

When constructing X:

ref_count = 0;
ref_weak_helper = NULL;

The "strong" pointer, intrusive_strong_ptr, is identical to intrusive_ptr, until deletion occurs. When the strong ref count goes to zero (before deletion occurs):

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

The "weak" version, intrusive_weak_ptr, records the pointer to the weak helper, manipulating that reference count, and accessing the target object via the target_instance pointer. When the weak_ref_count decrements to zero the status of target_instance determines whether the helper is deleted or not.

There are many details missing (concurrency concerns for instance) but this is a mixing of the shared_ptr and the intrusive_ptr. It maintains the basic benefits of the intrusive_ptr (cache optimization, reuse of 3rd party intrusive (strong) ref count, strong and weak pointer stand-ins are pointer sized) while adding extra work mainly in the weak reference path.

不语却知心 2024-08-31 01:44:09

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

如果您需要从this获取weak_ptr,您可能会搜索boost::enable_shared_from_this

Current implementation of intrusive pointer is using reference counter. So deleting object delete also delete the counter, so weak_intrusive_pointer will never know that the object was deleted.

If you need to get weak_ptr from this, you probably search boost::enable_shared_from_this<T>.

神经暖 2024-08-31 01:44:09

OpenSceneGraph 及其后继者 VulkanSceneGraph 均具有侵入式强指针和关联弱指针的全面实现,名为 ref_ptr<> 。和observer_ptr 分别。

我不知道这些系统的每个细节,但它们似乎使用一个附加对象来工作,当删除所指对象(Referenced 类的后代)时会通知该对象。当尝试将弱指针转换为强指针时,弱指针将使用第三个对象。

VulkanSceneGraph 是目前正在开发的下一代场景图,旨在取代 OpenSceneGraph,因此我认为它的侵入式指针系统是更高级的实现。

值得一看:

https://github。 com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/observer_ptr.h

OpenSceneGraph and its successor, VulkanSceneGraph, each have comprehensive implementations of intrusive strong pointers and associated weak pointers, named ref_ptr<> and observer_ptr<>, respectively.

I don't know every detail of these systems, but it seems they work using an additional object which is informed when the referent (a descendant of the class Referenced) is deleted. Weak pointers use this third object when an attempt is made to convert them to strong pointers.

VulkanSceneGraph is the next generation scene graph that is currently in development and intended to replace OpenSceneGraph, so I assume its intrusive pointer system is a more advanced implementation.

Worth checking out:

https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/observer_ptr.h

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文