避免在析构函数中无限递归
作为我的大学分配给我的练习的一部分,我编写了一个小的 Graph 实现,遵循这个标题。
class Node {
private:
std::string name;
std::vector<Node*> children;
public:
Node(const std::string& name="");
virtual ~Node();
}
在为析构函数编写代码时~Node(),我注意到当图形包含循环时我的实现失败。到目前为止,这是我的实现,如果图形包含循环,这显然不起作用。
Node::~Node() {
for (Node* n : children) {
delete n;
n = NULL;
}
children.clear();
}
我不确定如何最优雅地编写一个可以处理图中循环的析构函数?
请注意,我的任务是专门编写一个递归析构函数。谢谢您的回答!
回答
选项 1:为图选择一种表示形式,其中节点不属于其他节点,而是属于不同对象的图。这样节点析构函数不需要做任何事情。这将不满足递归的要求:
struct Graph {
std::vector<std::unique_ptr<Node>> nodes;
};
请注意,如果不涉及继承,那么您可以简单地使用std::vector<Node>. 我假设有,由于在Node.
或者,您可以使用另一种图形表示,例如邻接列表。
选项 2:使用算法生成图的最小生成森林。然后递归删除每个生成树的根。例如,您可以使用 Kruskal 算法。(根据您的表示,看起来您的图可能是连通的,在这种情况下,将只有一棵生成树)。