生成这个类的场景相当复杂,所以我将去掉几部分,并给出所涉及的类的准确表示。
/* 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();
}
};这就是构建和链接,但我不知道它是否有隐藏的bug。
发布于 2010-05-08 20:00:05
你可以使用“虚拟继承”来解决这个问题。
考虑创建一个仅定义纯虚拟toString方法的公共基类(或者,实际上,定义IBase和Base2都有意义的任何方法的纯虚拟版本),例如
class Stringable {
public:
virtual string toString() = 0;
};然后,让IBase和Base2都继承这个Stringable类:
class IBase : public Stringable
{
};
class Base2 : public Stringable
{
public:
virtual string toString()
{ ... }
};现在,这仍然不起作用,因为Class1将继承Stringable基类的两个副本,其中只有一个在其继承层次结构中具有toString的实现。这就是所谓的"dreaded diamond“。但是,如果IBase和Base2实际上继承自Stringable,如下所示:
class IBase : virtual public Stringable
{
};
class Base2 : virtual public Stringable
{
public:
virtual string toString()
{ ... }
};然后,这告诉编译器应该只有一个公共的Stringable基类,即使IBase和Base2都由一个类继承,这正是您想要的,因为Base2::toString用于Class1。
您的第二个想法没有“隐藏的bug”,但您可能意识到,重复实现它是一件很痛苦的事情。
发布于 2010-05-08 20:11:31
这应该可以很好地工作。
您正确地重写了IBase接口,从而提供了ToString()的定义,该定义将在Base2::ToString()之前被忽略。
请注意,Base2没有将toString()声明为虚拟的,因此Class1不能覆盖Base2::ToString的行为。没有模棱两可的地方。
此外,这不是virtual inheritance解决的多重继承中的经典菱形问题,因为它们不共享基类。
https://stackoverflow.com/questions/2793954
复制相似问题