gast128 wrote:
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.
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?