#include <memory>
struct S: enable_shared_from_this<S>
{
};
Don't do this:
S *p = new S;
shared_ptr<S> sp2 = p->shared_from_this(); // throws std::bad_weak_ref
Do this:
shared_ptr<S> p(new S);
shared_ptr<S> sp2 = p->shared_from_this();
Rule: when a class inherits from enable_shared_from_this, it almost always means it should work with shared_ptr together.
What happened behind the scene for shared_ptr<S> p(new S) ?
(1) enable_shared_from_this construct is called
(2) S constructor is called
(3) shared_ptr constructor is called (the magic happens here)
|
| -> __enable_shared_from_this_helper is called in shared_ptr constructor
|
|-> enable_shared_from_this::_M_weak_assign is called
|
|-> weak_ptr<_Tp>::._M_assign(__p, __n);
(called on mutable enable_shared_from_this::_M_weak_this instance in
struct S object. This calls sets (inits) the weak_ptr in struct S object)
|
|-> Set weak_ptr<_Tp>::_M_ptr and
weak_ptr<_Tp>:: _M_refcount (__weak_count<_Lp>)
Why the first case throws ?
// enabled_shared_from_this::shared_from_this
__shared_ptr<_Tp, _Lp> shared_from_this() { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
// __shared_ptr constructor with weak_ptr
template<typename _Tp1>
explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) : _M_refcount(__r._M_refcount)// may throw
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
// It is now safe to copy __r._M_ptr, as
// _M_refcount(__r._M_refcount) did not throw.
_M_ptr = __r._M_ptr;
}
// Throw bad_weak_ptr when __r._M_get_use_count() == 0.
explicit __shared_count(const __weak_count<_Lp>& __r): _M_pi(__r._M_pi)
{
if (_M_pi != 0)
_M_pi->_M_add_ref_lock();
else
__throw_bad_weak_ptr();
}