views:

622

answers:

3

Is there a standard way of maintaining a weak pointer to a parent (which is created using a shared pointer) in a child object in C++?

Essentially, I need to implement something on the lines of the following:

Class B;

Class A
{

...
private:
B m_b;
};

Class B
{
....
public:
void SetParentPtr(const boost::shared_ptr<A>& a)
{
m_parentPtr = a;
}
private:
boost::weak_ptr<A> m_parentPtr;
};

In the above all instances of class B need to hold a weak pointer to their parent (i.e object of class A). Class A objects are instantiated using a shared_ptr. I can think of a solution that uses a null deleter. But is that a standard way of doing something like this?

+3  A: 

What you are doing above is explicitly supported by weak_ptr and shared_ptr, what happens when you try it? To be more precise, do what you are doing, without the null deleter, and then you use the standard behaviour on the weak_ptr to convert it to a shared_ptr as needed:

boost::shared_ptr<X> it=myWeakPtr.lock();
if (it)
{
  // if the conversion succeeded, then the parent instance is still alive
}
1800 INFORMATION
+1  A: 

I would try to do something like this:

class A
{
A(){};

public:

static boost::shared_ptr<A> Create()
{
 boost::shared_ptr<A> newPtr(new A());
 newPtr->m_self = newPtr;
 return newPtr;
}

// ...

void CreateChild()
{
 m_childPtr = B::Create(m_self);
}

private:
boost::shared_ptr<B> m_childPtr;
boost::weak_ptr<A> m_self;
};

class B
{   
B(){};

public:

static boost::shared_ptr<B> Create(boost::shared_ptr<A> ptrA)
{
 boost::shared_ptr<B> newPtr(new B());
 newPtr->m_parentPtr = ptrA;
 return newPtr;
}

boost::weak_ptr<A> m_parentPtr;
};
Eugene
The enable_shared_from this paradigm as suggested by stefaanv IMHO is more suitable for what I was trying to do. It makes it transparent to the user to get a shared pointer from this within any member function of the parent - which can then be assigned to the weak pointer that the children hold.
anbhat
+2  A: 

There is an implicit conversion to weak_ptr, so you can use

void SetParentPtr(boost::weak_ptr<A> a) { }

directly.

check also boost::shared_from_this so the parent can give a pointer to himself without storing a weak_ptr explicitly.

Otherwise, this seems like a normal way to have a back-pointer. Just check whether there is a real added value in using back-pointers.

stefaanv