C++ 如何销毁包含自引用指针的对象?
我有一个树节点结构,其简单定义如下:C++ 如何销毁包含自引用指针的对象?,c++,pointers,memory-management,destructor,delete-operator,C++,Pointers,Memory Management,Destructor,Delete Operator,我有一个树节点结构,其简单定义如下: typedef struct TreeNode { int data; TreeNode *left; TreeNode *right; TreeNode *parent; TreeNode(int); ~TreeNode(); } TreeNode; 为了在销毁时释放左、右和父对象指向的内存(假设不为空),我制作了一个析构函数,如下所示: TreeNode::~TreeNode() { delet
typedef struct TreeNode {
int data;
TreeNode *left;
TreeNode *right;
TreeNode *parent;
TreeNode(int);
~TreeNode();
} TreeNode;
为了在销毁时释放左
、右
和父对象
指向的内存(假设不为空),我制作了一个析构函数,如下所示:
TreeNode::~TreeNode() {
delete left;
delete right;
delete parent;
}
但是,这样做会导致控件无限递归地删除TreeNode
对象,因为析构函数中的那些delete
语句调用相同结构的析构函数
问题:
- 释放自引用指针的正确方法是什么,特别是在析构函数内部
std::unique\u ptr
如果还去掉了多余的typedef
,则结构如下所示:
struct TreeNode {
int data;
std::unique_ptr<TreeNode> left;
std::unique_ptr<TreeNode> right;
TreeNode *parent{nullptr};
TreeNode() = default;
};
结构树节点{
int数据;
std::唯一左上角;
std::唯一的ptr权限;
树节点*父节点{nullptr};
TreeNode()=默认值;
};
现在,您无需执行任何操作,编译器将为您生成正确的解构器。正确的方法是不要使用拥有的原始指针,而是为子级使用
std::unique\u ptr
如果还去掉了多余的typedef
,则结构如下所示:
struct TreeNode {
int data;
std::unique_ptr<TreeNode> left;
std::unique_ptr<TreeNode> right;
TreeNode *parent{nullptr};
TreeNode() = default;
};
结构树节点{
int数据;
std::唯一左上角;
std::唯一的ptr权限;
树节点*父节点{nullptr};
TreeNode()=默认值;
};
现在您不需要做任何事情,编译器将为您生成正确的解构器。您最好阅读
std::unique\u ptr
、std::shared\u ptr
和std::weak\u ptr
。您不应该有一个包含TreeNode
的树
类吗,而树
类在必要时创建和销毁节点?您当前的设计通过删除单个节点来分解整个树。“如果你想删除一个节点?”杰斯珀,我真的只是从C++开始,所以直到我知道基本知识,然后我才会转到更高级的东西:D@Christian使用new
和delete
处理拥有原始指针和手动管理内存是高级功能。@你误解了。我试着给你们指出一个简单解决方案的方向。通过使用(老式的)手动内存管理,您已经走上了艰难的道路。您最好阅读std::unique_ptr
、std::shared_ptr
和std::weak_ptr
。您不应该有一个包含TreeNode
的树
类吗,而树
类在必要时创建和销毁节点?您当前的设计通过删除单个节点来分解整个树。“如果你想删除一个节点?”杰斯珀,我真的只是从C++开始,所以直到我知道基本知识,然后我才会转到更高级的东西:D@Christian使用new
和delete
处理拥有原始指针和手动管理内存是高级功能。@你误解了。我试着给你们指出一个简单解决方案的方向。通过使用(老式)手动内存管理,您已经开始走上了艰难的道路。对下行表决有何评论?是否调用父析构函数,只要我调用以删除父方法中的某个树节点;它会导致控件无限“递归”。你错了,因为如果(left){delete left;left=0;},如果(left){delete left;left=0;},它应该停止。如果(left){delete left=0;}有任何关于向下投票的注释吗?只要我调用父析构函数删除父方法中的某个树节点,就不会调用父析构函数;它会导致控件无限“递归”。这是错误的,因为如果(左){delete left;left=0;}