我有一个像这样的树状数据结构:
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();
之类的作业。我什至不知道这是否可能,不鼓励或鼓励。有编译器构造吗?我应该选择其中哪一个?非常感谢你!
答案 0 :(得分:0)
根节点类(或任何其他节点类)不应是接口类。保留它private
,然后没有动态多态性(virtual
)的继承并不危险,因为用户将永远看不到它。
禁止使用类似
Tree *root = new Root();
之类的作业。我什至不知道这是否可能,不鼓励或鼓励。有编译器构造吗?
这可以通过让Root
继承自Tree
作为私有基类来实现。