Boost logo

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