可以从'enable_shared_from_this'派生一个类来提高性能吗?

时间:2023-02-01 04:04:00

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).

make_shared比单独调用new和创建shared_ptr更高效,因为make_shared为客户端对象实例在同一内存块中为引用计数和弱计数分配空间(有效地为shared_ptr提供了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.

enable_shared_from_this提供共享指针,而不引用任何共享指针。因此,必须以某种方式从客户端对象内部访问诸如引用和弱计数之类的内容。因此,enable_shared_from_this导致类似于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?

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

3 个解决方案

#1


8  

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.

我从来没有深入研究实现的细节,但是为了使shared_from_this工作,该对象必须已经由外部shared_ptr管理,因此它在某种程度上是无关的。即第一个shared_ptr可能是用make_shared创建的,在这种情况下,count和object在一起(正如你所说的那样是侵入式指针),但不一定是这种情况。

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:

我的第一个猜测是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;
};

#2


1  

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.

我不相信。如何实现enable_shared_from_this并未严格定义,但标准中存在一个示例实现,该实现与boost的执行方式相对应。基本上,有一个隐藏的weak_ptr,shared_ptr和朋友可以访问...任何时候,shared_ptr被赋予从enable_shared_from_this派生的对象的所有权,它会更新该内部指针。然后shared_from_this()只返回该弱指针的强版本。

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.

在一般情况下,实现不能真正假设没有人会使用shared_ptr(new T)而不是使用make_shared,因此侵入式引用计数将是有风险的。相反,您可以通过用于构建对象的任何方式自己制作该保证。

#3


0  

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.

Boost的enable_shared_from_this不会改变shared_ptr本身的实现。请记住,shared_ptr与weak_ptr配对 - 这意味着,即使删除了对象,跟踪数据也可能需要保留,告诉weak_ptr对象已死。因此,即使使用enable_shared_from_this,它也无法嵌入到对象中。所有enable_shared_from_t这样做都是将指向所述跟踪数据的指针嵌入到对象中,因此可以仅使用指向该对象的指针来构造shared_ptr。

This is also why intrusive_ptr cannot have a weak_intrusive_ptr variant.

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

#1


8  

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.

我从来没有深入研究实现的细节,但是为了使shared_from_this工作,该对象必须已经由外部shared_ptr管理,因此它在某种程度上是无关的。即第一个shared_ptr可能是用make_shared创建的,在这种情况下,count和object在一起(正如你所说的那样是侵入式指针),但不一定是这种情况。

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:

我的第一个猜测是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;
};

#2


1  

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.

我不相信。如何实现enable_shared_from_this并未严格定义,但标准中存在一个示例实现,该实现与boost的执行方式相对应。基本上,有一个隐藏的weak_ptr,shared_ptr和朋友可以访问...任何时候,shared_ptr被赋予从enable_shared_from_this派生的对象的所有权,它会更新该内部指针。然后shared_from_this()只返回该弱指针的强版本。

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.

在一般情况下,实现不能真正假设没有人会使用shared_ptr(new T)而不是使用make_shared,因此侵入式引用计数将是有风险的。相反,您可以通过用于构建对象的任何方式自己制作该保证。

#3


0  

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.

Boost的enable_shared_from_this不会改变shared_ptr本身的实现。请记住,shared_ptr与weak_ptr配对 - 这意味着,即使删除了对象,跟踪数据也可能需要保留,告诉weak_ptr对象已死。因此,即使使用enable_shared_from_this,它也无法嵌入到对象中。所有enable_shared_from_t这样做都是将指向所述跟踪数据的指针嵌入到对象中,因此可以仅使用指向该对象的指针来构造shared_ptr。

This is also why intrusive_ptr cannot have a weak_intrusive_ptr variant.

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