|
Boost : |
Subject: [boost] Thoughts on make_shared and shared_from_this in a constructor
From: Peter Dimov (pdimov_at_[hidden])
Date: 2009-03-07 16:33:00
Let's take an example make_shared overload:
template< class T, class A1, class A2 >
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
{
boost::shared_ptr< T > pt( static_cast< T* >( 0 ),
detail::sp_ms_deleter< T >() );
detail::sp_ms_deleter< T > * pd = boost::get_deleter<
detail::sp_ms_deleter< T > >( pt );
void * pv = pd->address();
// #1
::new( pv ) T( a1, a2 );
pd->set_initialized();
T * pt2 = static_cast< T* >( pv );
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
return boost::shared_ptr< T >( pt, pt2 );
}
The primary problem with calling shared_from_this in a constructor is that a
shared_ptr to the object does not exist yet and may never will.
But, when using make_shared, at the line marked //#1 we do have a shared_ptr
that owns the storage of the future object T. So we should, in principle, be
able to return a copy of it from shared_from_this.
Unfortunately, we can't just move the sp_enable_shared_from_this call to #1
because (a) we can't convert an yet-unconstructed T to its
enable_shared_from_this base if there's virtual inheritance along the way,
and (b) even if we could, we can't initialize the weak_this_ member since
it's not constructed yet.
I can't think of a good way to pass this shared_ptr to the
enable_shared_from_this base since we have no control over T.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk