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?
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;
};
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With