Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2001-12-10 21:25:22


> I have run across a problem in some code that I am trying to convert
> to using shared_ptrs.
>
> Basically it looks something like...
>
> class A
> {
> public:
> init()
> {
> // Pass a ptr to myself to B so it can call me
> b_obj = new B(shared_ptr<A>(this));
> }
>
> B* b_obj;
> }
>
> class B
> {
> public:
> B(shared_ptr<A> aPtr)
> {
> a_obj = aPtr;
> }
>
> shared_ptr<A> a_obj;
> }
>
> Now in main...
>
> int main()
> {
> shared_ptr<A> a = new A;
> a->init();
>
> // Problem a and B::a_obj are
> // different shared_ptrs, pointing
> // to same object

Which of course would be a bad thing. Maybe this should be a
FAQ, but it is almost never right to traffic in raw pointers
in a shared_ptr design, and a trick like shared_ptr<A>(this)
is very dangerous when you don't know for certain that 'this'
is the only extant pointer to the object. It's a pity that
'this' isn't a reference, but that's another story. As for
shared_ptr, I think that shared_ptr<T>(new T) should always
be hidden away in a factory function, preferably with no
other way to contruct a T, and code should never otherwise
pass a raw pointer to a shared_ptr constructor.

Anyway, try something like this instead (warning, uncompiled
code off the top of my head):

class A
{
public:
   shared_ptr<A> init()
   {
      shared_ptr<A> a_ptr = new A;

      // Pass a ptr to myself to B so it can call me
      b_obj = new B(a_ptr);

      return a_ptr;
   }

   B* b_obj;
}

class B
{
public:
   B(shared_ptr<A> aPtr)
   {
      a_obj = aPtr;
   }

   shared_ptr<A> a_obj;
}

int main()
{
   shared_ptr<A> a = A::init();
}


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