2010-05-08 116 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解決,因爲它們不共享基類。