我创建了一个通用的树类(用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>
我希望这个例子清楚我的意图......
答案 0 :(得分:2)
如果A
是A
的树,则
但是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个。