2010-05-08 96 views
6

产生这种情况的场景非常复杂,所以我会去掉几块,并给出所涉及类的准确表示。C++多继承问题

/* 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

您可以使用“虚拟继承”来解决此问题。

考虑创建一个共同的基类,限定纯虚toString方法(或,在现实中,纯的任何方法虚拟版本是有意义的两个IBaseBase2有),例如

class Stringable { 
    public: 
    virtual string toString() = 0; 
}; 

然后,有从这个Stringable类都IBaseBase2继承:

class IBase : public Stringable 
{ 
}; 

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

现在这个,因为它仍然是行不通的,因为Class1将会继承了Stringable基地副本类,其中只有一个在其继承层次结构中具有toString的实现。这被称为“dreaded diamond”。但是,如果IBaseBase2是继承Stringable几乎,像这样:

class IBase : virtual public Stringable 
{ 
}; 

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

那么这告诉编译器应该只有一个共同的Stringable基类,即使IBaseBase2都是由一个继承类,这正是你想要的,因为Base2::toString用于Class1

您的第二个想法没有“隐藏的错误”,但是您可能会意识到,重复实施可能会有点痛苦。

1

这应该工作得很好。

您正在覆盖IBase界面以提供ToString()的定义,该定义将被废弃至Base2::ToString()

请注意,Base2不会将toString()声明为虚拟,因此Class1无法覆盖Base2::ToString的行为。那里没有歧义。

此外,这不是多个继承中的经典钻石问题,由virtual inheritance解决,因为它们不共享基类。