[smart_ptr] shared_from_this in constructor potential pitfalls

-----BEGIN PGP SIGNED MESSAGE----- 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. - -- Frank -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFH8oHq5vihyNWuA4URAuDiAJ4j2MAP8JvdOWf1neQifNzQXJxLvwCffUsf /atoUpoioLgDMtbvS2bKeRI= =MkM6 -----END PGP SIGNATURE-----
participants (1)
-
Frank Mori Hess