可以从“enable_shared_from_this”派生一个类提高性能?

发布于 2024-11-17 17:52:20 字数 573 浏览 2 评论 0原文

make_shared 比单独调用 new 并创建 shared_ptr 的性能更高,因为 make_shared 为引用计数和弱分配空间与客户端对象实例位于同一内存块中(有效地为 shared_ptr 提供了 intrusive_ptr 的大部分性能优势)。

enable_shared_from_this 给出一个共享指针,但不引用任何共享指针。因此,诸如引用和弱计数之类的东西必须能够以某种方式从客户端对象内部访问。因此,enable_shared_from_this 引起类似于 make_shared 的侵入计数是明智的。

然而,我不知道如何实现类似的东西(而且我不确定即使我查看实际的源代码我是否会遵循其中发生的事情)。

如果我知道它只会用作 shared_ptr 而永远不会用作原始对象,那么(出于性能原因)用 enable_shared_from_this 标记我的类是否有意义?

make_shared is more performant than separately calling new and creating a shared_ptr because make_shared allocates space for the reference count and weak count in the same memory block as the client object instance (effectively giving the shared_ptr most of the performance benefits of an intrusive_ptr).

enable_shared_from_this gives a shared pointer without having a reference to any shared pointer. Therefore things like the reference and weak count have to be somehow accessible from inside the client object. Therefore, it would be sensible for enable_shared_from_this to cause an intrusive count similar to make_shared.

However, I have no idea how something like that might be implemented (and I'm not sure I'd follow what was going on in there even if I look at the actual source).

Would it make sense then (for performance reasons) to tag my class with enable_shared_from_this if I know it's only ever going to be used as a shared_ptr and never as a raw object?

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

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

发布评论

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

评论(3

如日中天 2024-11-24 17:52:20

我从未深入研究过实现的细节,但要使 shared_from_this 工作,该对象必须已经由外部 shared_ptr 管理,因此它在某种程度上是不相关的。即第一个 shared_ptr 可能是使用 make_shared 创建的,在这种情况下,countobject 在一起(正如您比如说侵入式指针),但情况不一定如此。

我的第一个猜测是 enable_shared_from_this 添加了 weak_ptr 的等效项,而不是 shared_ptr编辑:我刚刚验证了 gcc4.6 中的实现:

template <typename _Tp>
class enable_shared_from_this {
...
mutable weak_ptr<_Tp> _M_weak_this;
};

I have never dug into the details of implementation, but for shared_from_this to work, the object must already be managed by an external shared_ptr, so it is to some extent unrelated. I.e. the first shared_ptr might have been created with make_shared in which case the count and object are together (as you say intrusive pointer like), but that does not need to be the case.

My first guess is that enable_shared_from_this adds the equivalent of a weak_ptr, rather than a shared_ptr. EDIT: I have just verified the implementation in gcc4.6:

template <typename _Tp>
class enable_shared_from_this {
...
mutable weak_ptr<_Tp> _M_weak_this;
};
寄离 2024-11-24 17:52:20

我不相信是这样。 enable_shared_from_this 的实现方式并未严格定义,但标准中提供了一个示例实现,与 boost 的实现方式相对应。基本上,有一个隐藏的 weak_ptrshared_ptr 和朋友可以访问......任何时候 shared_ptr 被授予派生自 shared_ptr 的对象的所有权code>enable_shared_from_this,它更新该内部指针。然后,shared_from_this() 只是返回该弱指针的强版本。

在一般情况下,实现不能真正假设没有人会使用 shared_ptr(new T) 而不是使用 make_shared,因此侵入性引用计数是有风险的。相反,您可以自己做出保证,无论您首先使用什么方式来构造对象。

I don't believe so. How enable_shared_from_this is implemented isn't strictly defined, but an example implementation is present in the standard that corresponds to how boost does it. Basicaly, there is a hidden weak_ptr that shared_ptr and friends has access to... anytime a shared_ptr is given ownership of an object derived from enable_shared_from_this, it updates that internal pointer. Then shared_from_this() simply returns a strong version of that weak pointer.

In the general case, the implementation can't really assume that nobody will ever go shared_ptr(new T) instead of using make_shared, so an intrusive reference count would be risky. You can instead make that guarentee yourself, by whatever means you use to construct the objects in the first place.

春风十里 2024-11-24 17:52:20

Boost 的 enable_shared_from_this 不会更改 shared_ptr 本身的实现。请记住,shared_ptrweak_ptr 配对 - 这意味着,即使在删除对象后,跟踪数据也可能需要保留下来以告知 weak_ptr code> 表明该对象已死亡。因此,即使使用 enable_shared_from_this,它也无法嵌入到对象中。 enable_shared_from_this 所做的只是将指向所述跟踪数据的指针嵌入到对象中,因此只需使用指向该对象的指针即可构造 shared_ptr

这也是 intrusive_ptr 不能有 weak_intrusive_ptr 变体的原因。

Boost's enable_shared_from_this does not change the implementation of shared_ptr itself. Remember that shared_ptr is paired with weak_ptr - this means that, even after the object is deleted, the tracking data may need to remain around to tell the weak_ptr that the object is dead. As such, it can't be embedded into the object, even with enable_shared_from_this. All enable_shared_from_this does is embed a pointer to said tracking data into the object, so a shared_ptr can be constructed with just a pointer to the object.

This is also why intrusive_ptr cannot have a weak_intrusive_ptr variant.

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