我对C ++还是很陌生,我正在做一些练习以更好地学习它。但是,我不了解给定任务的建议解决方案的析构函数中发生了什么。我试图在网上寻找一种解释,但还没有找到。
这是练习中给出的二叉树:
class Tree {
Tree *_left;
Tree *_right;
string _name;
public:
Tree(string name) : _left(NULL), _right(NULL), _name(name) {}
void insert(string name);
void insert(const Tree &tree);
friend ostream& operator<<(ostream&, const Tree&);
};
void Tree::insert(string name) {
Tree **destination = &_right;
if (name < _name) {
destination = &_left;
}
if (*destination == NULL)
(*destination) = new Tree(name);
else
(*destination)->insert(name);
}
练习是为此类创建一个析构函数。在网上找到的其他所有二叉树示例中,析构函数都以某种方式递归实现。但是解决方案手册建议这样做:
Tree::~Tree() {
delete _left;
delete _right;
}
这将如何工作?在我看来,这个析构函数只会删除一个节点的左右指针?还是这个析构函数也以某种方式递归?
答案 0 :(得分:3)
delete
-左右节点调用其析构函数。因此,所有资源都以递归方式释放。
如果表达式不是空指针[...],则删除表达式将调用 破坏者
或者从当前草案expr.delete#6
如果delete-expression的操作数的值不为null 指针值和选定的释放函数(如下所示)为 不是销毁运算符delete,则delete-expression将调用 对象或数组元素的析构函数(如果有) 被删除。
答案 1 :(得分:1)
在指针上调用delete
运算符时,将调用该对象的析构函数。因此,根据您的情况,该调用将沿二进制树传播。
除此之外,我想指出您的代码被认为是旧C ++ 。我了解您仍在学习,这只是一种练习。但理想情况下,您应该使用std::unique_ptr
或std::shared_ptr
之类的智能指针来管理指针所有权。这些类简化了代码,因为它们在您不再需要指向的对象时会自动销毁它们(例如,您的对象被销毁并且没有其他对象指向这些对象)。使用这些类型的指针时,您需要了解一些规则(例如,循环依赖可能是一个问题),但确实值得学习和使用。
我可以给你的另一个提示是停止使用NULL
,而开始使用nullptr
。
如果您想了解更多有关这些问题的信息,斯科特·迈耶斯(Scott Meyers)有一本书叫做 Effective Modern C ++ ,它解释了这些问题以及更多内容。