|
Boost Users : |
From: gast128 (gast128_at_[hidden])
Date: 2008-06-25 16:25:22
I already did a followup, but somehow it didn't come tru.
> Are consumers of this structure more likely to hold pointers to the
> parent or to a child?
>
> It sounds to me as though you want more direct control over the
> lifespans of parent and child. What if the parent's destructor were to
> delete all children outright? Then you'd never have orphans.
>
> You could hand out shared_ptrs to the parent object, so that it would
> persist as long as it had any consumers. As soon as the last consumer
> forgot about it, it would clean up all its own children.
>
> With that arrangement, you'd probably want direct consumers of the
> children to get weak_ptrs rather than shared_ptrs. That way a consumer
> could tell if the child had vanished.
>
> The parent should then hold the only shared_ptr to each child. (I'd
> suggest that the parent track its children with dumb child* pointers,
> but you need a shared_ptr on which to base your weak_ptrs.)
>
> And -- since you now know that the existence of a child implies the
> existence of its parent -- you could use dumb parent* pointers for the
> back-references from child to parent. That eliminates the need for the
> parent to obtain shared_from_this at constructor time.
>
> Does this address your constraints?
There are a number of solutions, like the one described above. But my hope was
to replace the raw pointer with a shared_ptr/weak_ptr/scoped_ptr for almost
any situation.
Dealing out a weak_ptr to a child, convert it to a shared_ptr when needed does
not prevent the parent getting deleted in a next sequence of calls, leading to
have a pointer to a child, without an exisitng parent. Other posts where about
the need for calling the parent during destruction. Well there is one major
case: if a parent is the observer of its child, the destructor of the child is
the ideal candidate for unregistering. But in above case it leads to crashes.
Although in this case the parent gets destroyed (in which the unregistering at
the parent may be superfluous) there may be other observers for the child.
All in all if I think about it, it can be solved (through a global register
for instance), but not with above described proposal, which was attractive due
to local character of the solution (child know only parents, maybe one class
more). Then again it seems that c# and a gc wouldn't help in this case either.
They break a cyclcic dependency, but it is forbidden to call object references
in finalizers. Then again to get at that stage all observing objcts to the
child had already give up their referneces, e.g soemthing like (in c++):
Parent::~Parent()
{
std::for_each(m_vChilds.begin(), m_vChilds.begin(),
boost::bind(&Parent::Notify, this, _1, eDelete);
//type std::vector< boost::shared_ptr<Child> >
m_vChilds.clear();
}
etc.
I know this sounds a little bit over the top, but we develop a pretty large
application in our company, where you can not track all pointer of lifetime of
object. Ideally a framework would solve lifetiem problems. Boost smart_ptr's
help (and do a great job), but not completely.
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