树结构的C++析构函数
C++ destructor for tree structure
我有这样的树结构:
public:
node(string& const n);
virtual ~node();
string get_name() const;
void set_name(string& new_name);
int get_nr_children() const;
node get_child(int i) const;
void add_child(node child);
private:
string& name;
vector<node> children;
};
我的main.cpp看起来是这样的:
int main() {
string s = "root";
node r(s);
string s2 = "left child";
node ls(s2);
string s3 = "right child";
node rs(s3);
r.add_child(ls);
r.add_child(rs);
r.~node();
}
(我知道~node()
在main
函数结束时在所有对象上运行,但我想确保它首先在根r
上执行)
到目前为止,除析构函数外,所有方法都运行良好。这是我的第一个析构函数,我想出了下面的递归尝试,但不知道为什么它不起作用。
node::~node() {
cout << "Enter ~node of " << this->get_name() << endl;
while (this->get_nr_children() != 0) {
this->get_child(0).~node();
this->children.pop_back();
}
delete this;
cout << "Leave ~node of " << this->get_name() << endl;
}
结果是"Enter ~ node of left child"的无休止输出
"(我知道~node()在主函数结束时会在所有对象上运行,但我想确保它首先在根r上执行)"
这句话足以说明这个问题的一切都是基于误解。
试图纠正甚至没有意义:完全重写是必要的。
相反,请阅读更多关于去分配器、它们的调用以及它们的用途的信息。
显式调用它不会抑制对它的隐式调用。双重破坏是未定义的行为。
此外,delete this
是一个非常棘手的问题,要求你必须非常确定它的含义。
并且在删除类方法(this->...
)或数据之后访问它们。。。只是在寻找麻烦。
如果编译,这是无效的,并产生未定义的行为
vector<node> children;
在这个数据成员声明的点上,类node
是不完整的;它的大小还不知道。
不能将不完整的类型用作标准库容器的项类型(但可以使用指针)。
在析构函数实现中,还有
delete this;
产生Undefined Behavior,一个调用析构函数的无限递归,析构函数(在这个delete
表达式中)调用自己,依此类推
数据成员声明
string& name;
它也有一种强烈的、令人不快的气味,但由于您没有显示构造函数的实现,我不能百分之百地肯定它是错误的。
然而,考虑到代码的其余部分,这是正确的可能性是无穷小的。只需使用
string name_;
通常,树使用在空闲存储上分配的节点。这意味着要贩运指向节点的指针,并删除不再使用的节点。问题中的代码没有遵循这个模型:它在堆栈上分配根节点,并在每个节点中存储节点对象而不是指针。有了这些代码,所有编译器生成的析构函数都可以正常工作。不需要任何用户定义的析构函数。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误