我想在程序中创建一个树结构。现在我有类似的东西:
class tree_node
{
public:
tree_node (tree_node* parent) : parent_(parent)
{
parent_.add_child(this);
}
private:
std::vector<tree_node*> children_;
tree_node* parent_;
}
我对这个设计的主要关注是tree_node
类可以删除它的任何子节点和父节点。我想改变设计以禁止这种情况。所以:
tree_node
班级删除孩子/父母吗?欢迎任何其他实现我的目标的想法。
答案 0 :(得分:7)
安全的解决方案是将子项存储为boost::shared_ptr并将父项存储为原始指针。然后,根节点将其父节点设置为null
。
回答你的问题:
- 我可以以某种方式更改设计以使用引用而不是指针吗? (引用的向量不起作用)。
在这种情况下你必须使用指针。参考文献根本不起作用。
- 我可以禁止通过tree_node类删除子级/父级吗?
在设计树时,最常识的所有权模型是节点拥有子女的所有权,反之亦然。
你说你想禁止一个班级为自己做点什么。这有什么意义?如果你不希望你的班级删除自己的孩子,那就干脆就不行了。
答案 1 :(得分:5)
编辑:回答标题中提到的问题而不是文本中提出的问题:最安全的方法是不重新实现树。使用标准库关联容器或可能提升BGL。
您可以在容器中使用引用包装器类(如果需要,还可以使用boost::optional
来保存父引用的包装器,但我不确定这是否是您的基础问题的解决方案。 tree_node
课程没有进行任何内存管理,因此没有特定的删除风险。
接下来,真的需要N-ary树吗?你可以使用std::map
或其他一个关联容器,避免编写一堆错误吗?
显然,您的树的公共API不应该提供对节点类的直接访问(检查map
及其对迭代器的使用),因此只要树正确管理内存,你对指针管理的担忧应该是最小的,因为你完全控制了节点的所有管理。
答案 2 :(得分:0)
您的类不进行任何内存管理,因此不会删除任何其他节点。如果你想确保任何使用tree_node类的人都没有删除任何父类或childeren,你需要将它们放入纯虚基类(它们是私有的)并让tree_node继承它。然后,强制使用tree_node的用户使用您提供的方法。
另外,如果你不想过多担心指针使用智能指针(参见boost :: shared_ptr)
答案 3 :(得分:0)
我可以看到为什么不允许孩子删除父节点,但我不明白你为什么不想删除孩子。这是树中最基本的操作之一。