我有一个像我这样设置的树状数据结构:
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;
};
我真的很喜欢这种结构,因为
Tree
上调用Root
上定义的所有递归函数,而不必将它们复制粘贴。但后来我意识到了一个问题。有人可能会无意中打来电话
Tree *root = new Root();
delete root; // memory leak! Tree has no virtual destructor...
这不是预期的用法(任何普通用法都应该在堆栈上有Root
)。但我愿意接受替代方案。现在,要解决这个问题,我有三个建议:
Tree
。我不希望这样做是因为开销因为树可以有许多节点。Root
从Tree
继承,而是让它定义自己的Tree
成员。创建一个小的间接,不太可怕,仍然可以通过做Tree
调用root.tree().recursive()
中的大量有用的递归函数。Tree *root = new Root();
这样的作业。我不知道这是否可能,或气馁或鼓励。有编译器构造吗?我更喜欢哪一个?非常感谢你!
根节点类(或任何其他节点类)不应该是接口类。保持private
然后继承没有动态多态(virtual
)并不危险,因为用户永远不会看到它。
禁止像
Tree *root = new Root();
这样的作业。我不知道这是否可能,或气馁或鼓励。有编译器构造吗?
这可以通过让Root
继承Tree
作为私人基类来完成。