Edit: unfortunately this is not a reliable
solution. See post below.
-------------------------------------------------------------------------------------
Hi,
just found a nice work-around for an issue that popped up now
and then. Posting here for future reference.
When you write your own class and create a shared_ptr
from it, sometimes you want to return a shared_ptr
of itself from one of its functions. The proper way to do this is
by deriving from
std::enable_shared_from_this :
typedef
std::shared_ptr<class MyClass> MyClassRef;
class
MyClass : public std::enable_shared_from_this<MyClass>
{
public:
MyClass() {}
virtual ~MyClass() {}
};
Now let's say, for the sake of argument, that you want to
register yourself for some kind of event:
void
MyClass::startListening( EventSender& source )
{
//
this will work
source.addListener( shared_from_this() );
}
The
documentation states that
shared_from_this()
only works if at least one strong reference to the
instance exists. And this means you can't use
shared_from_this()
in a constructor.
MyClass::MyClass( const MyClassRef& parent )
{
//
will generate a bad_weak_ptr exception, because no shared_ptr
//
has been created from this instance yet
parent->addChild( shared_from_this() );
}
The solution
I found is to create a temporary shared_ptr
while making sure
it will not destroy the instance when it goes out of scope.
For this, you supply a lambda function as a
custom deleter that does nothing:
MyClass::MyClass( const ParentRef& parent )
{
auto wptr =
std::shared_ptr<MyClass>( this, [](MyClass*){} );
// this will
work
parent->addChild( shared_from_this() );
}
I have
tested this and it works perfectly. Proper reference
counting is maintained, so you don't have to worry
about memory leaks.
-Paul