产生这种情况的场景非常复杂,因此我将删除一些内容并准确表示所涉及的类。
/* This is inherited using SI by many classes, as normal */
class IBase
{
virtual string toString()=0;
};
/* Base2 can't inherit IBase due to other methods on IBase which aren't appropriate */
class Base2
{
string toString()
{
...
}
};
/* a special class, is this valid? */
class Class1 : public IBase, public Base2
{
};
那么,这有效吗? toString会有冲突吗?或者Class1可以使用Base2 :: toString来满足IBase吗? 就像我说的那样,还有很多其他的东西没有显示出来,所以对这个例子的主要设计变更的建议可能没那么有用......虽然欢迎任何一般的建议/建议。
我的另一个想法是这样的:
class Class1 : public IBase, public Base2
{
virtual string toString()
{
return Base2::toString();
}
};
这构建和链接,但我不知道它是否隐藏了错误。
答案 0 :(得分:2)
您可以使用“虚拟继承”修复此问题。
考虑创建一个只有 定义纯虚拟toString
方法的公共基类(或者,实际上,对于IBase
两种方法都有意义的任何方法的纯虚拟版本和Base2
有,例如</ p>
class Stringable {
public:
virtual string toString() = 0;
};
然后,让IBase
和Base2
继承此Stringable
类:
class IBase : public Stringable
{
};
class Base2 : public Stringable
{
public:
virtual string toString()
{ ... }
};
现在这仍然无法正常工作,因为Class1
将继承{em}两个基类的副本,其中只有一个具有Stringable
基类的实现{1}}在其继承层次结构中。这被称为“dreaded diamond”。但是,如果toString
和IBase
要从Base2
继承虚拟,请执行以下操作:
Stringable
然后这告诉编译器,即使class IBase : virtual public Stringable
{
};
class Base2 : virtual public Stringable
{
public:
virtual string toString()
{ ... }
};
和Stringable
都由一个类继承,也应该只有一个公共IBase
基类,这正是你想要的,因为然后Base2
用于Base2::toString
。
你的第二个想法没有“隐藏的错误”,但是你可能会意识到,反复实施的屁股有点痛苦。
答案 1 :(得分:1)
这应该可以正常工作。
您正确地覆盖了IBase界面,以提供ToString()
的定义,该定义将被提升至Base2::ToString()
。
请注意,Base2
未将toString()声明为虚拟,因此Class1
无法覆盖Base2::ToString
的行为。那里没有歧义。
此外,这不是virtual inheritance解决的多重继承中的经典钻石问题,因为它们不共享基类。