Boost logo

Boost Users :

From: Richard L. Aurbach (rick_at_[hidden])
Date: 2008-06-20 21:53:12


On Jun 20, 2008, at 8:38 AM, gast128 wrote:

> Dear all,
>
> maybe this an off-topic issue, because it does not directly relate to
> shared_ptr and is more related to life time of objects and their
> validity
> during construction and destruction.
>
> There were the following issues:
> 1) childs validity depends on availability of parent and vise versa
> 2) in ctor one can not use the shared_from_this()
> 3) in destructor of the child the parent shared_ptr was inaccesible
>
> ad 1) the doc's are clear: you can not make a cycle in shared_ptrs
> between
> parent -> child and child -> parent. Thus now we use a weak_ptr for
> child ->
> parent, but actually the child can not exist without parent. So if
> one shares
> a child through a shared_ptr, a hypothetical situation could exist
> that its
> parent get destroyed, but a child lifes on (in an invalid state due
> to missing
> parent) because a client has requested it.
>
> ad 2) this is quite unhandy, since I thought it would be handy to
> let the
> parent create the childs passing itself. I think this can only be
> solved by
> two way construction.
>
> This may well turn out to be a fundamental problem. Consider two
> classes A and
> B which are associated with each other. Object of class A is valid
> when it is
> valid itself and when its associated object of class B is valid.
> When A gets
> changed it is temporalily invalid. It updates first B, but if B asks
> services
> from A during that call, it asks an invalid object. Reversing the
> order may
> help, but A may have to update itself again after it calls B. For
> two related
> classes it can be overseen, but of course real life applications
> have 1000 or
> more classes. Btw to some extend Bertrand Meyer's book touches this
> subject,
> but he only mentions the problem within a class (with public and
> private
> members).
>
> ad 3) the destructor of the child needed the parent to call another
> class.
> However the parent was inaccessible because it was destroyed itself.
> This is
> of course also a fundamental problem because when an object gets
> destroyed not
> all of its members may be valid (the parent object is in an invalid
> state), so
> calling the parent at that time was questionable too. The real
> problem was
> that it needed form the parent its parent which was still valid,
> solutions are
> obvious (but ugly)
>
> Sample code:
>
> struct Child;
> struct Parent;
>
> struct Child
> {
> Child(boost::shared_ptr<Parent> ptrParent)
> {
> m_ptrParent = ptrParent;
> }
>
> ~Child()
> {
> boost::shared_ptr<Parent> ptrParent = m_ptrParent.lock();
> if (ptrParent)
> {
> //never come here
> }
> }
>
> boost::weak_ptr<Parent> m_ptrParent;
> };
>
> struct Parent : public boost::enable_shared_from_this<Parent>
> {
> Parent()
> {
> //won't work:
> //m_ptrChild.reset(new Child(shared_from_this()));
> }
>
> boost::shared_ptr<Child> m_ptrChild;
> };
>
>
> void TestParentChild()
> {
> boost::shared_ptr<Parent> ptrParent(new Parent);
> ptrParent->m_ptrChild.reset(new Child(ptrParent));
> }
>
> wkr,
> me

When I use shared_ptr and weak_ptr in parent/child relationships, I
tend to take a different tack.

First of all, I like to use the concept of a "master" shared_ptr. That
is, I attempt to design my architectures so that there is one
shared_ptr which persists for the lifetime of the object being pointed
to; other shared_ptrs are transient, in that they persist for a
shorter period of time (typically which a particular piece of work is
being performed). To pursue the metaphor, the "master" shared_ptr
holds its object in existence. It is the pointer which (when reset)
ultimately causes the object to be deleted.

Using this concept, my parent object holds the master shared_ptr of
its child. (Typically there are multiple children and their master
shared_ptrs are stored in a vector.) The child holds a weak_ptr to its
parent. In my work, typically both parent and child inherit from
enable_shared_from_this.

The "trick" is to treat the parent-child relationship seriously. Since
child objects do not exist except in the context of a parent, it is
logical to create a function member of the parent which is responsible
for creating the child and establishing linkages. (Or, if this needs
to occur elsewhere, the child is constructed by some other [third-
party] object's member function which creates the child and links the
child and parent together.) It should not be necessary to construct
the child in the parent's constructor, nor should it be necessary to
establish linkages with the parent in the child's constructor. The
problems you are concerned about need not exist. As long as the
construction of the child and its linkage to its parent occur in a
single member-function, it should not be necessary for either the
parent's or the child's constructor to be responsible for establishing
the linkage.

Cheers,

Rick Aurbach, Ph.D.
President and Chief Engineer
Aurbach & Associates, Inc.
8233 Tulane Avenue, Suite B
St. Louis, MO 63132

www: http://www.aurbach.com/
eMail: support_at_[hidden] [business]
                rick_at_[hidden] [personal]
Fax: 314/678-0869
Phone: 800/774-7239
                 314/726-1321

"If it ain't broke and you haven't fixed it recently, it probably
needs to be rewritten." - Richard Aurbach (1948- )
"Beware of bugs in the above code; I have only proved it correct, not
tried it." - Donald Knuth, computer scientist (1938- )
"If in the last few years you haven't discarded a major opinion or
acquired a new one, check your pulse. You may be dead." - Gelett
Burgess (1866-1951)
"A life spent making mistakes is not only more honorable, but more
useful than a life spent doing nothing." - George Bernard Shaw
(1856-1950)
"It doesn't matter how beautiful your theory is, it doesn't matter how
smart you are. If it doesn't agree with experiment, it's wrong." -
Richard Feynman (1918-1988)
"The most likely way for the world to be destroyed, most experts
agree, is by accident. That's where we come in; we're computer
professionals. We cause accidents." - Nathaniel Borenstein (1957-)



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