Boost logo

Boost :

From: Frank Mori Hess (frank.hess_at_[hidden])
Date: 2008-04-01 14:41:41

Hash: SHA1

It has occurred to me, constructors which throw exceptions might cause
difficulties with the new support for calling shared_from_this() from
constructors. If a constructor uses shared_from_this(), then throws an
exception, it may result in dangling shared_ptrs (or the BOOST_ASSERT in the
enable_shared_from_this destructor getting triggered).

The problem can be avoided by not calling shared_from_this until you are sure
your constructor won't throw. However, suppose you have a hierarchy such
as "U derived from T derived from enable_shared_from_this<T>". Then if the
constructor of U throws, it could be difficult to clean up any shared_ptr
objects created by shared_from_this calls in the T constructor.

Another tactic would be to restrict oneself to storing weak_ptrs when using
shared_from_this() in constructors, and not locking any of them until the
object is fully constructed. An exception thrown later in a constructor
would cause the weak_ptrs to expire.

This kind of tactic might be enforced by dropping support for shared_from_this
in constructors. Instead, we would have a method in enable_shared_from_this
which, instead of returning a shared_ptr like shared_from_this(), returns
some object (call its class "shared_from_that" for the moment) with a method
(say, shared_from_that::get()) that will return a shared_ptr to the original
object when one is available. If the object is not owned by a shared_ptr
yet, then shared_from_that::get could return an empty shared_ptr. If the
object has destructed without ever being owned by a shared_ptr, or its owning
shared_ptrs have expired, then shared_from_that::get() could throw
bad_weak_ptr. Then client code would be able to distinguish between the two
possible failures of either the shared_ptr not being available yet, or being
expired, and act accordingly. An slightly different formulation might be
a "weak_from_that" class, with a get() method that returns a weak_ptr and
throws if the original object doesn't have an owning shared_ptr yet.

I'm still on the fence as to whether shared_from_that would be an improvement
or not. It seems more honest and safer than shared_from_this in
constructors, but less convenient and a more complicated interface.

- --
Version: GnuPG v1.4.6 (GNU/Linux)


Boost list run by bdawes at, gregod at, cpdaniel at, john at