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

C++ 实现树结构最安全的方法是什么?,c++,pointers,reference,tree,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_no

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

class tree_node
{
    public:
        tree_node (tree_node* parent) : parent_(parent)
        {
            parent_.add_child(this);
        }

    private:
        std::vector<tree_node*> children_;
        tree_node* parent_;
}
类树\u节点
{
公众:
树节点(树节点*父节点):父节点(父节点)
{
父项添加子项(此项);
}
私人:
性病:病媒儿童;
树节点*父节点;
}
我主要关心的是
树节点
类可以删除它的任何子节点和父节点。我想改变设计,不允许这样做。因此:

  • 我可以改变设计,使用引用而不是指针吗?(参考向量不起作用)
  • 如果使用引用,如何处理根节点(没有父节点)的特殊情况
  • 我是否可以禁止通过
    树节点
    类删除子/父节点

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

一个安全的解决方案是将子对象存储为原始指针,将父对象存储为原始指针。然后,根节点将其父节点设置为
null

回答您的问题:

  • 我可以改变设计,使用引用而不是指针吗?(参考向量不起作用)
在这种情况下,您必须使用指针。引用根本不起作用

  • 我是否可以禁止树节点类删除子节点/父节点
在设计树时,最常见的所有权模型是节点拥有其子节点的所有权,反之亦然


你是说你想禁止一个类对自己做一些事情。这有什么意义?如果你不想让你的类删除它自己的子类,那就不要这样做。

一个安全的解决方案是将子类存储为原始指针,将父类存储为原始指针。然后,根节点将其父节点设置为
null

回答您的问题:

  • 我可以改变设计,使用引用而不是指针吗?(参考向量不起作用)
在这种情况下,您必须使用指针。引用根本不起作用

  • 我是否可以禁止树节点类删除子节点/父节点
在设计树时,最常见的所有权模型是节点拥有其子节点的所有权,反之亦然


你是说你想禁止一个类对自己做一些事情。这有什么意义?如果你不想让你的类删除它自己的子类,那就不要这样做。

你的类不做任何内存管理,因此它不会删除任何其他节点。如果您想确保使用树节点类的任何人都不会删除任何父节点或子节点,则需要将它们放入纯虚拟基类(它们是私有的)中,并让树节点从中继承。然后,使用tree_节点的用户将被迫使用您提供的方法


另外,如果您不想太担心指针,请使用智能指针(请参阅boost::shared_ptr)

您的类不进行任何内存管理,因此它不会删除任何其他节点。如果您想确保使用树节点类的任何人都不会删除任何父节点或子节点,则需要将它们放入纯虚拟基类(它们是私有的)中,并让树节点从中继承。然后,使用tree_节点的用户将被迫使用您提供的方法


此外,如果您不想太担心指针,请使用智能指针(请参阅boost::shared_ptr)

编辑:回答标题中提出的问题,而不是文本中提出的问题:最安全的方法是不重新实现树。使用标准库关联容器或boost BGL

您可以在容器中使用一个引用包装器类(如果需要,还可以使用一个为父引用保存此类包装器的
boost::optional
),但我不确定这是否是解决潜在问题的方法。
tree\u节点
类不进行任何内存管理,因此不存在特定的删除风险

接下来,你真的需要一个N元树吗?您是否可以使用
std::map
或其他关联容器,避免编写大量bug


显然,树的公共API不应提供对节点类的直接访问(请查看
map
及其迭代器的使用),因此只要树正确管理内存,您对指针管理的担忧应该是最小的,因为您可以完全控制节点的所有管理。

编辑:要回答标题中而不是文本中提出的问题,最安全的方法是不重新实现树。使用标准库关联容器或boost BGL

您可以在容器中使用一个引用包装器类(如果需要,还可以使用一个为父引用保存此类包装器的
boost::optional
),但我不确定这是否是解决潜在问题的方法。
tree\u节点
类不进行任何内存管理,因此不存在特定的删除风险

接下来,你真的需要一个N元树吗?您是否可以使用
std::map
或其他关联容器,避免编写大量bug


显然,树的公共API不应提供对节点类的直接访问(请查看
map
及其迭代器的使用),因此只要树正确管理内存,您对指针管理的担忧应该是最小的,因为您可以完全控制节点的所有管理。

我可以理解为什么不允许子节点删除父节点,但我不理解您为什么不允许删除子节点。这是树中最基本的操作之一

我明白为什么不能允许子节点删除父节点,但我不明白为什么要禁止删除子节点。这是最重要的问题之一