通用树类的继承

时间:2015-08-11 14:13:04

标签: c++ generics inheritance tree class-design

我创建了一个通用的树类(用C ++编写,但我认为没关系)。 Tree类具有泛型类的成员,保存为List。例如:

template <T> class Tree {
    public: List<T> childs;
}

现在我有一个A类,它应该是一个由A类元素组成的树。如:

class A : public Tree<A>...

这很好用。所以我的A类对象有一个属性childs作为A类对象列表。

问题是,现在我想创建一个B类,它是B的元素树(就像上面的A类一样),但它也继承了A类。喜欢:

class B: public Tree<B>, public A...

所以孩子的名字冲突发生了。我想要的是,树的元素不再是A,而是现在的B类。我认为我的方法在许多方面都是错误的,这是我的问题

有没有一种很好的方法来创建B类元素的树?

提前致谢。

编辑:作为一个例子:我有树的类,我为人类创建了一个类。对于人类的家庭部分,我想使用树(在这个例子中,每个人只有1个父...)。所以每个人都是树,孩子是其他人(人类的子女)。现在我想要另一个班级,例如女性。一个女性显然是一个人,我也可以创造一个女性树,但这棵树应该只包含其他女性!所以总之我想:

class Human : public Tree<Human>
class Female : public Human, public Tree<Female>

我希望这个例子清楚我的意图......

4 个答案:

答案 0 :(得分:2)

如果AA的树,则 但是B不是A的树,
然后B不能是A。为什么会这样?

答案 1 :(得分:2)

这提出了composition vs. inheritance的常见问题。

不是树列表。树是某种类型元素的容器。树具有元素。因此,元素应该在树中通过组合(通用树的成员)而不是通过继承。

如果您想看到精彩的容器设计,请查看标准库。您有标准容器,但这些容器都不需要从容器继承元素

如果你遵循这个方向和最佳实践,你将拥有Tree<A>Tree<B>,并且绝对没有问题。通过这种架构,您可以充分利用separation of concerns

顺便说一句,在您考虑的多重继承中,您将拥有2棵树:从A继承的树,以及从中继承的树 Tree<B>

修改:

我试图用你编辑的例子来说,人类可能出现在树上但不是自己的树。这可能听起来很哲学,但它是课堂设计的一个重要方面:如果两个类之间的关系意味着“是一个”,那么你应该只使用继承。如果你不遵守这条规则,你迟早会遇到困难。在你的例子中,更快。

现在,如果您想要不惜一切代价遵循这种方式,可能会有一种解决方法:

template <T> class Tree {
    public: List<shared_ptr<T>> childs;  // use pointers
};
class A : public Tree<A>; 
class B : public A; 

在这种情况下,元素A存储指向其子节点的指针(最好是原始指针上的shared_ptr<>)。并且每个指针都可以指向A或其任何派生类。您最终可以控制B的可访问界面,以便仅在需要时添加B子项。

答案 2 :(得分:1)

为什么不使用更像这样的模板:

template <typename T> class Tree {
    public: List<Tree<T> > children;
}

现在您不必从A继承Tree<A> 为了制作树的递归结构, 或B继承自Tree<B>。 你可以定义

class B : public A

然后

class TreeOfB : public Tree<B>

答案 3 :(得分:0)

很难理解你究竟想要获得什么,但多重继承通常不是一个很好的实践(除非你是从抽象类继承)。

您可以使用聚合/组合而不是继承,并让Tree成为您的类的成员。

另一种可能性是让A成为模板类,继承自A&lt; B个。