2011-12-19 49 views
1

我需要通過使其受到保護從基類中抽象出很多接口,但是我還需要公共訪問一個簡單的祖先類Object。我可以在沒有對這些祖先的寫/編輯訪問權的情況下協商dreaded diamond,並且仍然只提供基本的API,但是會再次公開Object的API嗎?C++多重繼承,基類可見性和可怕的鑽石。重新公開祖先基類?

class Object { 
    virtual bool Equals (const Object &obj) const; 
    virtual int GetHashCode (void) const; 
}; 

class ComplicatedOne : public Object { 
    //Lots of funcs I don't want or need. 
}; 

class Line : protected ComplicatedOne, public Object { 
    //Some funcs of ComplicatedOne get re-implemented or called by alias here 
public: 
    virtual bool Equals(const Object &obj) const { 
     return Object::Equals(obj); 
    } 
    virtual int GetHashCode() const { 
     return Object::GetHashCode(); 
    } 
}; 

class Array { 
    void Add (Object &obj); 
    Object *GetAt (int i); 
}; 

main() { 
    Array a; 
    a.Add(new Line()); 
} 

回答

2

您可以使用組合。

您可以持有ComplicatedOne作爲成員的實例,並公開您需要的內容。

這樣你可以保持它的保護,但永遠不會有鑽石的情況。

此外,如果ComplicatedOneObject,所以LineObject通過繼承,所以你不需要再繼承。

1

你對於你真正的問題是非常模糊的,但對我來說,聽起來好像你想使用繼承來獲得代碼重用。
你不應該這樣做。看看這個article
對我來說,聽起來好像組成更多你想要的。在您的班級中創建ComplicatedOne的成員,並將呼叫委託給此成員。那麼你不需要從它繼承。

+0

沒錯,我要在組合被調用時帶着繼承性而瘋狂。 – John

0
return Object::Equals(obj); 

這不能編譯,因爲它是不明確的:有兩個Object基本對象。

另外,轉化率從Line*Object*是模糊的,並且該模糊性不能被解析到第二Object基類(在左到右的基類的順序),所以第二Object基不用於任何目的,除了創建困難。

目前尚不清楚你準備做什麼:ComplicatedOne類代表什麼?爲什麼你從它繼承,如果你打算重新覆蓋每個虛擬函數?

+0

儘管'ComplicateOne'包含了'//我不想或不需要的許多funcs',它仍然有其用途。 – John