实现树结构最安全的方法是什么?

时间:2011-12-01 16:07:22

标签: c++ pointers reference tree

我想在程序中创建一个树结构。现在我有类似的东西:

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班级删除孩子/父母吗?

欢迎任何其他实现我的目标的想法。

4 个答案:

答案 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)

我可以看到为什么不允许孩子删除父节点,但我不明白你为什么不想删除孩子。这是树中最基本的操作之一。