【发布时间】:2019-04-21 21:18:44
【问题描述】:
我有一个类似树的数据结构,我这样设置:
class Root; // forward declaration
class Tree {
public:
void addChildren(Root &r, ...) { childA = r.nodeSpace.allocate(); ... }
// tons of useful recursive functions here
private:
Tree *childA, *childB, *childC;
Tree *parent;
int usefulInt;
};
class Root : public Tree {
friend class Tree; // so it can access our storage
public:
private:
MemoryPool<Tree> nodeSpace;
};
我真的很喜欢这种结构,因为
- 我也可以在
Root上调用Tree上定义的所有递归函数,而无需复制粘贴它们。 - Root 拥有存储空间,因此每当它超出范围时,这就是我将树定义为不再有效的方式。
但后来我意识到一个问题。有人可能会不小心打来电话
Tree *root = new Root();
delete root; // memory leak! Tree has no virtual destructor...
这不是预期的用法(任何普通用法都应该在堆栈上有Root)。但我对替代品持开放态度。现在,为了解决这个问题,我有三个建议:
- 将虚拟析构函数添加到
Tree。我宁愿不这样做,因为树可以有很多很多节点。 - 不要让
Root继承自Tree,而是让它定义自己的Tree成员。创建一个小间接,不是太糟糕,仍然可以通过root.tree().recursive()调用Tree中大量有用的递归函数。 - 禁止分配
Tree *root = new Root();。我不知道这是否可能或不鼓励或鼓励。有编译器构造吗? - 还有别的吗?
我应该更喜欢哪一个?非常感谢!
【问题讨论】:
-
关于选项#3,看起来可能在这里:stackoverflow.com/questions/124856/…
标签: c++ inheritance tree composition