Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can deriving a class from 'enable_shared_from_this' increase performance?

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?

like image 930
Billy ONeal Avatar asked Jun 28 '11 22:06

Billy ONeal


2 Answers

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;
};
like image 151
David Rodríguez - dribeas Avatar answered Nov 07 '22 09:11

David Rodríguez - dribeas


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.

like image 24
Dennis Zickefoose Avatar answered Nov 07 '22 09:11

Dennis Zickefoose