Boost logo

Boost :

Subject: Re: [boost] [smart_ptr] enable_shared_from_this and shared_ptr to a base class
From: Jonathan Wakely (jwakely.boost_at_[hidden])
Date: 2013-06-24 06:05:44

On 24 June 2013 10:22, Adam Romanek wrote:
> On 06/24/2013 10:06 AM, Jonathan Wakely wrote:
>> 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.

No, that's not how shared_ptr's ownership works. It owns a pointer
and when the last owner releases ownership the pointer is passed to
the deleter (which might just call 'delete'). But there is no
requirement that the pointer is non-null, or points to an instance of
some specific type, and certainly no requirement that if the
shared_ptr owns an X* that it has anything to do with any instance of
a different type Y, even if Y is related to X by inheritance. The
shared_ptr doesn't care about such things, it just owns a pointer and
arranges for it to be passed to the relevant deleter at the
appropriate time.

In this example the four shared_ptr objects all share ownership of the
same pointer of type Y*, even though one of them is a shared_ptr<X>
and one is shared_ptr<void> and one stores a completely unrelated
pointer type, but still owns a pointer of type Y*:

struct X { virtual ~X() {} };
struct Y : X { };

std::shared_ptr<Y> sy(new Y);
std::shared_ptr<X> sx(sy);
std::shared_ptr<void> sv(sx);
std::shared_ptr<int> si(sv, (int*)0);

The ownership is a property of the static type of the pointer passed
to the first shared_ptr constructor that creates a unique shared_ptr
(i.e. one with use_count()==1). If you don't pass a Y* to the first
constructor then it doesn't own a Y* and won't initialize any
enable_shared_from_this<Y> base class.

> So maybe "ownership" should be described in more detail?

Yes, if people are making up their own interpretations of it then
maybe it should be.

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