Boost logo

Boost :

From: Larry Evans (jcampbell3_at_[hidden])
Date: 2002-01-20 16:24:25


Peter Dimov wrote:

> From: "Larry Evans" <jcampbell3_at_[hidden]>
> > Thomas Maeder wrote:
> >
> > > Am 2002.01.19 14:23 schrieb(en) David Abrahams:
> > > >
> > > > ...which is the reason it might be better if they didn't implicitly
> > > > convert, unless Peter's precautions are taken.
> > >
> > > Are there equivalent precautions against
> > >
> > > shared_ptr<Base> b(new Derived);
> > >
> > > ?
> > >
> >
> > The following test driver snippet:
>
> [...]
>
> > where "struct subjAB :public A,public B{...}", when compiled and run with
> > "gcc version 3.1 20011207 (experimental)", fails to delete a_make.
> >
> > I am using Peter's
> http://groups.yahoo.com/group/boost/files/smart_ptr_3.zip.
>
> True, there is no way to detect the general case where a shared_ptr is being
> constructed from a T * that actually points to something derived from T.
>
> Easy cases like the above example can be detected (QoI) but in general, it
> is a precondition of the shared_ptr(T * p) constructor that "delete p" will
> work, and it is the user's responsibility to meet that precondition.
>
> Once the pointer has been successfully constructed (the precondition has
> been met) it becomes shared_ptr's responsibility to do the right thing on
> destruction.
>

Unless I'm crazy :) the main advantage of shared_ptr from:

  http://groups.yahoo.com/group/boost/files/smart_ptr_3.zip

over the prox_mi from the *prox.cpp file in:

  http://groups.yahoo.com/group/boost/files/2001/GarbageCollectByTmplSpecializa/prox_mi.zip

is that shared_ptr only has 1 template parameter. Thus, shared_ptr
seems less restrictive. However, the 2nd template parameter of
shared_ptr is actually "hidden" in "shared_count::counted_base*
pi_;". This is because:

           shared_ptr<T>::shared_ptr( T * p = 0)
calls shared_count::shared_count(T*p,checked_deleter<T> d)
does counted_base* shared_count::pi_ = new counted_base_impl<T*, checked_deleter<T> >(p, d, 1, 1);

The reason why the following code works:

  struct A{}; struct B{}; struct AB: public A,B{};
 AB*pAB=new AB;
 shared_ptr<AB> spAB(pAB);
 shared_ptr<B> spB(spAB);
 spAB.reset();

is because the shared_ptr<B> CTOR copies the shared_count::pi_ whose
virtual dipose calls the correct deleter, checked_deleter<T>.

So my question is, why should the AB type be hidden in the
shared_ptr<B> instance, spB? Why not make it explicit, as done with
prox_mi<B,AB> (see example code in the *prox.cpp in the prox_mi.zip).
My first guess at the reason is that the user might not know the most
derived class of the pB in the above code. For example, it could be
AB or any other class having B as a superclass; hence, shared_ptr can
be used in more situations. But in the above code, the user does know
the most derived class. He knows it must be AB since the argument
he's using to shared_ptr<B> is a shared_ptr<AB>. Could someone
describe a case where this is not so, i.e. the user does not know what
the most derived class is when creating a shared_ptr<T>?

Please help clear the fog from my head if I'm wrong.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk