C ++:树根应该使用继承而不是组合吗?

问题描述 投票:0回答:1

我有一个像我这样设置的树状数据结构:

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;
};

我真的很喜欢这种结构,因为

  1. 我也可以在Tree上调用Root上定义的所有递归函数,而不必将它们复制粘贴。
  2. Root拥有存储空间,因此每当它超出范围时,我就会将树定义为不再有效。

但后来我意识到了一个问题。有人可能会无意中打来电话

Tree *root = new Root();

delete root; // memory leak! Tree has no virtual destructor...

这不是预期的用法(任何普通用法都应该在堆栈上有Root)。但我愿意接受替代方案。现在,要解决这个问题,我有三个建议:

  • 将虚拟析构函数添加到Tree。我不希望这样做是因为开销因为树可以有许多节点。
  • 不要让RootTree继承,而是让它定义自己的Tree成员。创建一个小的间接,不太可怕,仍然可以通过做Tree调用root.tree().recursive()中的大量有用的递归函数。
  • 禁止像Tree *root = new Root();这样的作业。我不知道这是否可能,或气馁或鼓励。有编译器构造吗?
  • 别的什么?

我更喜欢哪一个?非常感谢你!

c++ inheritance tree composition
1个回答
0
投票

根节点类(或任何其他节点类)不应该是接口类。保持private然后继承没有动态多态(virtual)并不危险,因为用户永远不会看到它。

禁止像Tree *root = new Root();这样的作业。我不知道这是否可能,或气馁或鼓励。有编译器构造吗?

这可以通过让Root继承Tree作为私人基类来完成。

© www.soinside.com 2019 - 2024. All rights reserved.