【问题标题】:How to destruct object containing self-referential pointer?如何销毁包含自引用指针的对象?
【发布时间】:2017-09-25 13:25:32
【问题描述】:

我有一个树节点结构,简单定义为:

typedef struct TreeNode {
    int data;
    TreeNode *left;
    TreeNode *right;
    TreeNode *parent;

    TreeNode(int);
    ~TreeNode();
} TreeNode;

为了在销毁时释放leftrightparent对象指向的内存(假设不为空),我制作了一个析构函数如下:

TreeNode::~TreeNode() {
    delete left;
    delete right;
    delete parent;
}

但是,这样做会导致控件无限递归地删除 TreeNode 对象,因为析构函数中的那些 delete 语句调用了相同结构的析构函数。


问题:

  • 释放自引用指针的正确方法是什么,特别是在析构函数内部?

【问题讨论】:

  • 您最好阅读std::unique_ptrstd::shared_ptrstd::weak_ptr
  • 你不应该有一个包含TreeNodeTree 类,并且Tree 类在必要时创建和销毁节点吗?您当前的设计通过删除单个节点来解开整个树。如果只想删除一个节点怎么办?
  • @Jesper 我真的只是从 C++ 开始,所以在我了解基础知识之前,我才会转向更高级的东西:D
  • @Christian 处理拥有原始指针并使用newdelete 手动管理内存高级的东西。
  • @Christian 你误会了。我试图为您指明simple 解决方案的方向。您已经通过使用(老式)手动内存管理开始了hard路径。

标签: c++ pointers memory-management destructor delete-operator


【解决方案1】:

如果您不调用父析构函数,它应该可以工作。但是,如上所述,该节点下方的整个树将被删除。

【讨论】:

  • 反对投票有什么意见吗?
  • 调用父析构函数与否,只要我调用删除父方法某处的树节点即可;它会导致控件无限“递归”。
  • 你错了,如果没有更多链接的子对象,它应该停止if(left){delete left;left=0;}
【解决方案2】:

正确的方法是不要使用拥有的原始指针,而是使用std::unique_ptr 代替子级。

如果你也去掉了多余的typedef,结构体看起来像这样:

struct TreeNode {
    int data;
    std::unique_ptr<TreeNode> left;
    std::unique_ptr<TreeNode> right;
    TreeNode *parent{nullptr};

    TreeNode() = default;
};

现在你不需要做任何事情,编译器会为你生成正确的解构器。

【讨论】:

    猜你喜欢
    • 2012-11-30
    • 2015-06-14
    • 1970-01-01
    • 2022-01-06
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    相关资源
    最近更新 更多