Boost logo

Boost Users :

From: Darren Vincent Hart (dvhart_at_[hidden])
Date: 2003-08-23 09:26:47


If I understand you problem right it comes down to not being able to
pass a shared_ptr to "this"?

If so, I had a similar problem in another project. My solution was for
the "parent" class to have a member: boost::weak_ptr<parent> weak_this_
and a static named constructor. I have found that named constructors
are one of your best friends in C++, they solve all those problems of
"what can I do in the constructor?". The named constructor is called
parent::create, and looks something like this:

shared_ptr<parent> parent::create()
{
        share_ptr<parent> new_parent = shared_ptr<parent>(new parent());
        new_parent->set_weak_this(new_parent);
        return new_parent;
}

The shared_ptr new_parent is automatically converted to a weak_ptr when
assigned with "set_weak_this" (you must store it as a weak_ptr or you
will have double deletion problems - ie segfaults). Now to your
problem, when you need to create a child using a smart_ptr to a parent
"this", do it like this:

    // not sure if this can be const anymore...
    boost::shared_ptr<Child> CreateChild()
    {
        boost::shared_ptr<Child> child(new Child(weak_this_.lock()));
        return child;
    }

That's it, you now have the ability to pass a shared_ptr to this by
storing a weak_ptr to this and locking it as needed, and the user code
will look something like:

parent::ptr my_parent = parent::create();
child::ptr my_child = my_parent->CreateChild();

note: typedef boost::shared_ptr<parent> ptr; goes in the public section
of the parent class header file.

Darren Hart
dvhart_at_[hidden]

On Fri, 2003-08-22 at 10:57, Martin Ecker wrote:
> Hello,
>
> I've been thinking of switching one of my projects to
> use boost::smart_ptr and I'm currently investigating
> this option a bit.
>
> In my project there are a lot of cases where an object
> acts as factory/parent object to create other child
> objects.
> These child objects must keep the parent object
> alive as long as one of them still exists. Or in other
> words, even if the client does not hold a pointer to
> the parent object anymore, the parent must continue
> to exist as long as there is still a child object.
> Also the child objects sometimes need to have
> access to the parent object that created them.
> Therefore, I thought I'd have them hold a shared_ptr
> to the parent object.
>
> So the situation looks something like this, where
> both Parent and Child objects are only allocated on the
> heap and should only be passed around as shared_ptr.
>
> class Parent
> {
> public:
> boost::shared_ptr<Child> CreateChild() const
> {
> boost::shared_ptr<Child> child(new Child(this));
> return child;
> }
> };
>
> class Child
> {
> friend class Parent;
>
> protected:
> Child(const boost::shared_ptr<Parent> parent)
> : m_parent(parent)
> {}
>
> private:
> boost::shared_ptr<Parent> m_parent;
> };
>
> As far as I understand it I can't do new Child(this) because
> Child expects a shared_ptr, so I'd have to derive Parent from
> enable_shared_from_this.
> However, in my project there are a number of classes in a rather
> complicated class hierarchy to which the above pattern applies
> and I'd thus like to avoid having to (multiply) derive them from
> enable_shared_from_this.
> Is there another, possibly better way of achieving what I
> want to do (keep the parent alive as long as there are still
> child objects) that I haven't discovered yet? Or do I really
> have to derive all these classes from enable_shared_from_this?
> Do I have to derive each class in a class hierarchy from
> enable_shared_from_this, if each of them needs to give
> out a shared_ptr-managed this pointer?
>
> Thanks for any help,
> Martin
>
>
>
> Info: <http://www.boost.org>
> Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl>
> Unsubscribe: <mailto:boost-users-unsubscribe_at_[hidden]>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net