从我的理解,这个二进制搜索树析构函数的代码可以工作:
~tree(){
remove(root);
}
void remove(node* root)
{
if (root == NULL) return;
remove(root->left);
remove(root->right);
delete root;
}
但是,我想知道以下对析构函数的调用是否有效?
~node(){
delete left;
delete right;
}
~tree(){
delete root;
}
我的理解是删除root会自动调用子节点并删除它们。这是正确的假设吗? 如果它确实正确,验证析构函数是否正常工作的简单方法是什么?
{{此部分帖子后来添加了}}
我在这里使用第二种方法。通过输出表达式验证,下面的代码似乎不起作用,因为我得到一个删除输出(似乎是根节点)
struct node{
~node(){
delete left;
delete right;
}
};
class tree {
node* root;
public:
tree(){
root=NULL;
}
~tree(){
cout<<"Deleting: "<<endl;
delete root;
}
void insert (int x){};
}
int main(){
A.insert(12);A.insert(13);A.insert(10);
return 0;
}
以下是我得到的输出:
Deleting:
理想情况下,应该有3个这样的表达式,但我只得到1个。
答案 0 :(得分:2)
是的,如果叶子节点的左边和右边等于nullptr,它将起作用。
根据C ++标准(5.3.5删除)
6如果delete-expression 的操作数值不为null 指针值,delete-expression 将调用析构函数 (如果有的话)对象或要删除的数组的元素。在 在数组的情况下,元素将按顺序销毁 减少地址(即,完成的相反顺序) 他们的建设者;见12.6.2)。
因此,仅当节点不是空指针值时才会调用节点的析构函数。
如果要检查析构函数是否确实有效,则只需在析构函数体中插入一个输出语句。
这是一个示范程序
#include <iostream>
struct node
{
node *next;
int x;
~node()
{
std::cout << "inside node: " << x << std::endl;
delete next;
}
};
void push_front( node **tree, int x )
{
node *n = new node;
n->x = x;
n->next = *tree;
*tree = n;
}
void clear( node **tree )
{
delete *tree;
*tree = nullptr;
}
int main()
{
node *tree = nullptr;
for ( int i = 0; i < 10; i++ ) push_front( &tree, i );
clear( &tree );
}
输出
Compiled with /EHsc /nologo /W4
main.cpp
Compilation successful!
Total compilation time: 187ms
inside node: 9
inside node: 8
inside node: 7
inside node: 6
inside node: 5
inside node: 4
inside node: 3
inside node: 2
inside node: 1
inside node: 0
Total execution time: 734ms
答案 1 :(得分:0)
不,这不起作用,因为析构函数允许在delete
指针上调用NULL
。