可以从“enable_shared_from_this”派生一个类提高性能?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我从未深入研究过实现的细节,但要使
shared_from_this
工作,该对象必须已经由外部shared_ptr
管理,因此它在某种程度上是不相关的。即第一个shared_ptr
可能是使用make_shared
创建的,在这种情况下,count 和 object 在一起(正如您比如说侵入式指针),但情况不一定如此。我的第一个猜测是
enable_shared_from_this
添加了weak_ptr
的等效项,而不是shared_ptr
。 编辑:我刚刚验证了 gcc4.6 中的实现:I have never dug into the details of implementation, but for
shared_from_this
to work, the object must already be managed by an externalshared_ptr
, so it is to some extent unrelated. I.e. the firstshared_ptr
might have been created withmake_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 aweak_ptr
, rather than ashared_ptr
. EDIT: I have just verified the implementation in gcc4.6:我不相信是这样。
enable_shared_from_this
的实现方式并未严格定义,但标准中提供了一个示例实现,与 boost 的实现方式相对应。基本上,有一个隐藏的weak_ptr
,shared_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 hiddenweak_ptr
thatshared_ptr
and friends has access to... anytime ashared_ptr
is given ownership of an object derived fromenable_shared_from_this
, it updates that internal pointer. Thenshared_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 usingmake_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.Boost 的
enable_shared_from_this
不会更改shared_ptr
本身的实现。请记住,shared_ptr
与weak_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 ofshared_ptr
itself. Remember thatshared_ptr
is paired withweak_ptr
- this means that, even after the object is deleted, the tracking data may need to remain around to tell theweak_ptr
that the object is dead. As such, it can't be embedded into the object, even withenable_shared_from_this
. Allenable_shared_from_this
does is embed a pointer to said tracking data into the object, so ashared_ptr
can be constructed with just a pointer to the object.This is also why
intrusive_ptr
cannot have aweak_intrusive_ptr
variant.