C++多重继承问题

6

这个情景非常复杂,因此我将剥离一些部分,并准确地呈现所涉及的类。

/* 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();
 }
};

这个构建并链接了,但我不知道它是否存在隐藏的错误。

2个回答

2
你可以使用“虚拟继承”来解决这个问题。
考虑创建一个公共基类,仅定义一个纯虚拟的 toString 方法(或者在实际中,定义另外一些对于 IBaseBase2 都有意义的纯虚拟方法),例如:
class Stringable {
  public:
    virtual string toString() = 0;
};

然后,让IBaseBase2都继承自Stringable类:
class IBase : public Stringable
{
};

class Base2 : public Stringable
{
public:
   virtual string toString()
   { ... }
};

现在这个代码仍然不能正常工作,因为Class1继承了Stringable基类的两个副本,其中只有一个在其继承层次结构中实现了toString。这被称为“可怕的菱形继承问题”。然而,如果IBaseBase2Stringable进行虚拟继承,像这样:
class IBase : virtual public Stringable
{
};

class Base2 : virtual public Stringable
{
public:
   virtual string toString()
   { ... }
};

那么这告诉编译器,即使一个类同时继承了IBaseBase2,也应该只有一个共同的Stringable基类,这正是您想要的,因为这样Base2::toString就可以用于Class1

您的第二个想法没有“隐藏的错误”,但实现起来有些麻烦,您可能已经意识到了。


1

这应该可以正常工作。

您正在正确地覆盖IBase接口,以提供对ToString()的定义,该定义将被转发到Base2 :: ToString()

请注意,Base2未将toString()声明为虚拟函数,因此Class1无法覆盖Base2 :: ToString的行为。没有任何歧义。

此外,这也不是由于虚拟继承解决的多重继承中的经典钻石问题,因为它们不共享基类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接