views:

119

answers:

2

I have two classes with a parent-child relationship (customer&order directory&file etc)

I have

typedef boost::shared_ptr<Parent> ParentPtr

and in parent class a method to make a child

I need child instances to have pointers to their parent.

class Child
{
 ....
     ParentPtr m_parent;
 ....
}

I want it to be a shared_ptr so that the parent doesn't disappear while there are existing children. I also have other people holding ParentPtrs to the parent (the factory method for Parents returns a ParentPtr)

Question: how can give the child a ParentPtr

attempt (1) . In Parent::ChildFactory

child->m_parent.reset(this);

this results in very bad things. There are now 2 ParentPtr 'chains' pointing at the parent; result is premature death of Parent

attempt (2). Parent has

ParentPtr m_me;

which is copied from the return value of the Parent factory. So I can do

child->m_parent = m_me;

But now Parent never dies because it holds a reference to itself

+7  A: 

I'm fairly sure that enable_shared_from_this solves your problem: http://live.boost.org/doc/libs/1_43_0/libs/smart_ptr/enable_shared_from_this.html

If you derived your class from a specialization of boost::enable_shared_from_this then you can use shared_from_this() in a member function to obtain the shared pointer that owns this (assuming that there is one).

E.g.

class Parent : public boost::enable_shared_from_this<Parent>
{
    void MakeParentOf(Child& c)
    {
        c.m_parent = shared_from_this();
    }
};
Charles Bailey
great answers - thanks
pm100
@pm100: Why do you need to use a `weak_ptr`? If the children own their parents (shared betweem them) then you need to use a `shared_ptr`. A `weak_ptr` does not imply ownership.
Charles Bailey
oh yes you are correct - I was thinking of a different solution - removing edit
pm100
i could have had the parent have a weak pointer to itself that it could use to generate the shared_ptr that it could pass to children (like my m_me), but the enable_share makes this not necessary (I suspect thats what it does under the hood)
pm100
A: 

As the other response has pointer out, first you'll have to use the enable_shared_from_this to get the shared_ptr, but then the child can't hold that ref, it must use a weak_ptr. A weak_ptr is just like a shared_ptr except that it won't hold a reference until you call the get() method, which will return you a normal shared_ptr which you should get rid of as soon as you can inside the child.

Gianni
Why do you think this? The model is that the children (together with "other people") own their parents; the parents don't own the children. If the children use a weak pointer then it won't prevent the parents from "disappearing" while they still have children in existence.
Charles Bailey
@Charles Sorry, my bad. I'm assuming things that weren't explicitly mentioned: I assumed that if `shared_ptr` and `weak_ptr` were used, parents were going to have ref's to their children. I assumed that, just because, by default, parents control their children, until at least they turn 18 and leave home. If it is the other way round, please ignore everything I said.
Gianni
Well, I don't know exactly what the structure of pm100's code is but I was reasoning that if he is concerned about parents being destroyed while they still had children then the parent class couldn't own (either directly by value or via a `shared_ptr`) the child classes otherwise it wouldn't even be a consideration. The ownership relationship would ensure that a child couldn't outlive its last parent. As it is, it's my understanding that the required ownership is the other way around: "I want it to be a shared_ptr so that the parent doesn't disappear while there are existing children."
Charles Bailey
Well, I guess it depends on what the code is like, but anyway, between us, we gave all that he might need, one way or the other. ;-)
Gianni