
On Mon, Feb 4, 2013 at 6:23 PM, Nathan Crookston
Since Foo embeds a weak_ptr, why can't it new the pi_ on the spot? (I'm using Boost 1.44).
Hmm, it might be interesting to have shared_from_this create a shared_ptr if none exists, but I don't know what that might complicate -- perhaps it would cause issues at destruction?
I don't see the difference between the shared_ptr being created from the "inside" or the "outside", as far as that pi_ is concerned.
PS: On a related note, why doesn't boost::shared_ptr<Foo>(p_foo) (where p_foo is a raw Foo*) implicitly apply the aliasing Ctor, to share the same px, to avoid the classic bug of having several different pn on the same px, since p_foo derives from enable_shared_from_this()? Initially i thought that's what sp_enable_shared_from_this() and pe->_internal_accept_owner() were meant to do, but obviously that's not the case.
I suspect something like this could be made to work if the previous also worked -- but the class is documented to *not* allow the previous to work. I'd have to think about why (or maybe Peter will enlighten us).
Indeed, I (naively) think it can work, and I'm interested in finding out why this was not implemented, especially whether it was conscious decision (rational?) or simply overlooked. There's already code that tightly couples shared_ptr/weak_ptr/enable_shared_from_this, so it seems that making shared_ptr even safer in the special case that T is-a enable_shared_from_this<T>, to enforce using a single pn (the one embedded in the base enable_shared_from_this<T>) given a T*, is a "good thing", no? I've emulated that behavior using shared_from_ptr() below, to avoid a crash from the "normally big NO-NO!" line in the test (also below), just as a proof-of-concept, although of course catching the exception like this is hardly pretty. Could easily be made to work whether T is-a boost::enable_shared_from_this<T> or not too, but really we'd want this little machinery to be built-in to shared_ptr, don't you think? Thanks for any insight on this. Could very well be I'm missing something obvious (my C++ expertise doesn't rise to Boost levels), but so far I fail to see the drawbacks. Thanks, --DD struct Foo : boost::enable_shared_from_this<Foo> { static int count__; Foo() { ++count__; } ~Foo() { --count__; BOOST_ASSERT(count__ >= 0); } }; int Foo::count__ = 0; template <typename T> boost::shared_ptr<T> shared_from_ptr(T* p_t) { try { boost::enable_shared_from_this<T>* p_this = p_t; // for more obvious error messages return p_this->shared_from_this(); } catch (const boost::bad_weak_ptr&) { return boost::shared_ptr<T>(p_t); } } BOOST_AUTO_TEST_SUITE(MY_TEST) BOOST_AUTO_TEST_CASE(test_shared_from_ptr) { BOOST_CHECK(Foo::count__ == 0); { boost::shared_ptr<Foo> foo_ptr1 = shared_from_ptr(new Foo); BOOST_CHECK(Foo::count__ == 1); BOOST_CHECK(foo_ptr1.unique()); BOOST_CHECK(foo_ptr1.unique()); boost::shared_ptr<Foo> foo_ptr2 = shared_from_ptr(foo_ptr1.get()); // normally big NO-NO! BOOST_CHECK(Foo::count__ == 1); BOOST_CHECK(!foo_ptr1.unique()); BOOST_CHECK(!foo_ptr2.unique()); } BOOST_CHECK(Foo::count__ == 0); } ...