用于建模一般树结构及其迭代器的智能指针

Mic*_*aut 2 c++ boost iterator smart-pointers

我通过为每个节点创建一个类来建模一般的树结构,其中包含指向父节点,第一个子节点和第一个兄弟节点的指针,以及指向最后一个兄弟节点的指针(不需要但很有用).对此,我正在添加一些额外的数据atd.我目前的实施是:

class TreeNode {
    typedef boost::shared_ptr<TreeNode> Ptr;
    typedef boost::weak_ptr<TreeNode> WPtr;

    WPtr p2parent;     ///< pointer to the parent node (NULL in the root)
    Ptr p2sibling;     ///< pointer to the first sibling (or NULL)
    Ptr p2child;       ///< pointer to the first child (or NULL)
    WPtr p2lastChild;  ///< pointer to the last child (not strictly needed)
};
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在使用shared_ptr用于兄弟和子节点,因此只需删除其根目录即可删除整个树.对于指向parent的指针,我知道我不应该使用shared_ptr,因为这会创建循环,所以我必须在weak_ptr和原始指针(TreeNode*)之间做出选择 - 任何想法?

对于指向最后一个子节点的(可选)指针,选择在weak_ptr,shared_ptr和原始指针之间 - 什么是使整个类内部一致的最佳选择?

最后,我在结构上有几个迭代器,比如深度优先迭代器atd.迭代器应该在内部使用什么指针:raw pointer,weak_ptr或shared_ptr?这三种方法有哪些优点?

Jam*_*lis 6

shared_ptr是完全矫枉过正:它是一棵树,所以没有节点的共享所有权.每个节点都有一个所有者:其父级.

如果您使用的实现支持它,您应该使用std::unique_ptr两个子指针和指向根节点的指针.如果您的实现不支持std::unique_ptr,您可以使用std::auto_ptr但是您希望显式地使节点类不可复制.在任何一种情况下,您都可以使用原始指针将指针返回到父级.

(请注意,无论您使用何种类型的指针,您都需要为树类编写复制构造函数和复制赋值运算符:隐式声明的指针不具有正确的语义.)

迭代器只需要一个指向它所指向的元素的原始指针.


Jan*_*dec 3

对于父指针:您必须确保它始终指向父级中子级的 setter 中的实际父级,因此向Treenode析构函数添加 unset 相对简单。在这种情况下,哑指针就可以了。

对于最后一个子指针:使其保持最新需要更多的工作,如果您完成这项工作,您会发现您涵盖了所有情况,并且不需要任何其他情况的智能指针。所以哑指针在这里也可以做。

您可以使用它weak_ptr来获得一点额外的安全性,尽管您实际上应该断言它们没有过期,因为这意味着您忘记取消设置它们,并且可能意味着您没有正确管理它们。

迭代器:应该使用智能指针。

  • 如果他们使用shared_ptr,即使您修改树并将其断开连接,他们也会使子树保持活动状态。
  • 如果它们使用weak_ptr,则当删除指向的节点时,它们将失效(您必须检查指针在许多地方是否仍然有效)。

选择取决于您想要哪种语义。