I want to create a tree structure in my program. Right now I have something similar to the following:
class tree_node
{
public:
tree_node (tree_node* parent) : parent_(parent)
{
parent_.add_child(this);
}
private:
std::vector<tree_node*> children_;
tree_node* parent_;
}
My main concern with this design is that the tree_node class can delete any of its children and the parent. I want to change the design to disallow this. So:
- Can I somehow change the design to use references instead of pointers? (vector of references does not work).
- If I use references, how can I treat the special case of the root node (which has no parent)?
- Can I disallow the deletion of children/parents by the
tree_nodeclass?
Any other ideas to achieve my goal are welcome.
EDIT: To answer the question asked in the title but not in the text: The safest way is to NOT re-implement a tree. Use a standard library associative container or possibly boost BGL.
You could use a reference wrapper class within containers (and a
boost::optionalholding such a wrapper for the parent reference if desired), but I’m not sure this is a solution to your underlying problem. Thetree_nodeclass doesn’t do any memory management so there isn’t a particular risk of deletion.Next, do you really need an N-ary tree? Could you get away with
std::mapor one of the other associative containers and avoid coding up a bunch of bugs?Obviously your tree’s public API shouldn’t provide direct access to the node class (check out
mapand its use of iterators), so as long as the tree is properly managing the memory, your worries about pointer management should be minimal because you fully control all management of the nodes.