On 06/24/2013 10:06 AM, Jonathan Wakely wrote:
On 24 June 2013 08:22, Adam Romanek wrote:
You wrote that there is no shared_ptr pointing to Y in my code. I can't agree. There is - sp. It points to Y through a pointer to X, which is perfectly valid. Moreover, in my opinion it "owns" an instance of Y and will attempt to destroy it when necessary.
No it won't, the program has undefined behaviour because X::~X() is not virtual.
Yep, my bad. But this discussion is not about destroying X / Y correctly.
Don't upcast the Y* to X* before giving ownership to a shared_ptr, that's a bug in your code. Everything works if you fix that.
Even if the destructor was virtual (so the code didn't have undefined behaviour) your expectation of enable_shared_from_this is wrong. For it to work would require a dynamic_cast in every shared_ptr constructor taking a raw pointer, to check if the X* points to a base class of a Y*. That would add unacceptable overhead for many people.
I haven't thought about implementation implications of using enable_shared_from_this the way I used it in the example code. Please note that this was just an example. The issue arose in a more complicated code where things are not so simple and easy to catch.
The documentation says that there must be a shared_ptr that owns t, where t is an instance of T (in your case T is Y). That is not true for your program, for a shared_ptr to "own" a pointer t it must have been constructed with a copy of _that_ pointer, not some other pointer with a different type to some base class of the same object. The shared_ptr owns the pointer it was constructed with, and you do not construct it with a Y*, so no shared_ptr owns a pointer to your Y object.
When taking inheritance into account one can safely say that a pointer to a base class X pointing to an instance of a derived class Y owns this instance. That's my point of view. So maybe "ownership" should be described in more detail?
I think there is a small documentation bug though, enable_shared_from_this talks about owning an object of type T, but the shared_ptr docs talk about owning a pointer. The docs for std::enable_shared_from_this correctly say "There shall be at least one shared_ptr instance p that owns &t." (as opposed to "owns t"). The & should be added to the Boost docs.
WBR, Adam Romanek