Remarks on enable_shared_from_this
std::enable_shared_from_this is a template base class that allows
derived classes to get a
std::shared_ptr to themselves. This can be
handy, and it's not something that C++ classes can normally do. Calling
std::shared_ptr<T>(this) is not an option as it creates a new shared pointer
independent of the existing one, which leads to double destruction.
The caveat is that before calling the
shared_from_this() member function, a
shared_ptr to the object must already exist, otherwise undefined behavior results.
In other words, the object must already be managed by a shared pointer.
This presents an interesting issue. When using this technique, there are member
functions (those that rely on
shared_from_this()) that can only be called if
the object is managed via a
shared_ptr. This is a rather subtle requirement:
the compiler won't enforce it. If violated, the object may even work at runtime
until a problematic code path is executed, which may happen rarely – a nice
little trap. At the very least, this should be prominently mentioned in the
class documentation. But frankly, relying on the documentation to
communicate such a subtle issue sounds wrong.
The correct solution is to let the compiler enforce it. Make the
constructors private and provide a static factory method that returns a
shared_ptr to a new instance. Take care to delete the copy constructor
and the assignment operator to prevent anyone from obtaining
non-shared-pointer-managed instances this way.
Another point worth mentioning about
enable_shared_from_this is that the
member functions it provides,
public. Not only the object itself can retrieve it's owning
everyone else can too. Whether this is desirable is essentially an API design
question and depends on the context. To restrict access to these functions,
use private inheritance.
enable_shared_from_this is an interesting tool, if a bit
situational. However, it requires care to use safely, in a way that prevents
derived classes from being used incorrectly.