2012-01-27 225 views
4

我在C++中需要很少的繼承幫助。我有這樣的代碼:在C++中實現接口

class IBase { 
public: 
    virtual long Dimensions() = 0; 
}; 

class IShape : public IBase { 
    virtual long Area() = 0; 
}; 

class Rectangle : public IShape { 
private: 
    long x; 
public: 
    long Dimensions() {return x}; 
    long Area() {return x*x}; 
}; 

class Rhombus: public IShape { 
private: 
    long x; 
    long fi; 
public: 
    long Dimensions() {return x}; 
    long Area() {return x*x*sin(fi)}; 
}; 

正如你所看到的,Dimensions()的實現對於這兩個類都是相同的。現在我wan't做這樣的事情:

class BaseImplementation : public IBase { 
protected: 
    long x; 
public: 
    virtual long Dimensions() {return x}; 
}; 

class Rectangle : public IShape, public BaseImplementation { 
public: 
    long Area() {return x*x}; 
}; 

class Rhombus: public IShape, public BaseImplementation { 
private: 
    long fi; 
public: 
    long Area() {return x*x*sin(fi)}; 
}; 

可以插入實現方法尺寸()成菱形類從BaseImplementation的?這在某些版本的C++標準中是否受到支持? Thx。

+0

@CharlesB這不是一般的壞主意分離接口繼承和混合插件(缺省實現)。這是一種非常常見的技術。 – 2012-01-27 11:15:18

+0

@ user1173308你的意思是「插入類的方法的實現」究竟是什麼意思?你想重寫'Rhombus'類的'Dimensions()'的行爲嗎? – CharlesB 2012-01-27 11:15:26

+0

@KonradRudolph:謝謝,我不習慣這個。刪除了評論,因爲它是錯誤的。 – CharlesB 2012-01-27 11:16:54

回答

3

與層次的問題是,你Rectangle現在繼承IBase兩次:一次通過IShape,並通過BaseImplementation。稱爲Virtual Inheritance的C++功能旨在處理這種情況。請注意,您還需要使IShape繼承IBasevirtual public

1

如果Dimensions()BaseImplementation中實現,並且在訪問中至少爲protected,則它應該對任何派生對象都可見。

所以Rhombus將能夠使用Dimension()函數,如果它來自BaseImplementation。如果你想爲Dimension()一個具體實施的Rhombus的情況下,你的Dimension()應該是virtual,你應該重寫它Rhombus

+0

如果試圖創建對象菱形。 GCC(g ++)顯示此錯誤:不能將變量'xyz'聲明爲抽象類型'菱形'注:因爲以下虛函數在'菱形'內是純的:virtual long int IBase :: Dimensions() – zdenek 2012-01-27 11:35:00

0

沒有必要顯式插入實現。您可以調用 myRhombus-> Dimension(),因爲它是繼承的。

1

你可以簡單地實現在之間的層定義尺寸:

class IBase { 
public: 
    virtual long Dimensions() = 0; 
}; 

class IShape : public IBase { 
public: 
    virtual long Area() = 0; 
}; 

class IShapesDefinedDimension : public IShape 
{ 
public: 
    long Dimensions() { return x; } 
protected: 
    long x; 
}; 

class Rectangle : public IShapesDefinedDimension { 
public: 
    long Area() {return x*x;} 
}; 

class Rhombus: public IShapesDefinedDimension { 
public: 
    long Area() {return x*x*sin(fi); } 
... 
    };