2017-02-02 49 views
0

我創建了一個名爲'iDrawableObject'的接口,其中包含對象的所有圖形相關方法/成員。在接口構造函數中調用重寫的接口方法

該接口還包含虛擬方法,例如「裝飾」,其中派生類可以更改它們在屏幕上顯示的方式。

我在iDrawableObject接口的構造函數中調用裝飾方法,但是,正如預測的那樣,它不會調用覆蓋的方法。 這是因爲接口的構造函數在派生類的構造函數之前運行,因此該方法尚未被覆蓋。

我發現這種困境的另一種方法是在派生類的構造函數中手動調用重載的「裝飾」方法。然而,這對我來說似乎很不好,因爲它很容易忘記,可以說是一種附加的「依賴」。

我的問題是:什麼是具有呼籲派生類中重寫「裝飾」法不強制實施者手動調用它在每一個派生類的構造函數的最好方法(它是安全的假設所有使用該接口的類將需要調用它們自己的裝飾實現)。

謝謝!

class iDrawableObject { 

    public: 

    iDrawableObject() 
    { 
     registerWithGameEngine(this); 
     decorate(); 
    } 

    ~iDrawableObject() 
    { 

    } 

    void draw() 
    { 
     ... // Draws it on screen 
    } 
    virtual void decorate() 
    { 
     renderGraphic = SquareGraphic(...); 
    } 

    protected: 

    Graphic renderGraphic; 
    Vector2f positionOnScreen; 

}; 

class Circle 
    : 
    public iDrawableObject; 
{ 
    public: 

    Circle(Vector2f _pos) 
     : 
     positionOnScreen(_pos) 
    {  
    } 

    void decorate() override 
    { 
     renderGraphic = CircleGraphic(...); 
    } 

}; 

int main() { 

    Circle c = Circle(Vector2f(0.0f, 0.0f); 

    c.draw();   // A Square is drawn on screen 
    c.decorate();  // Now calls the overriden method 
    c.draw()    // A Circle is drawn on screen 

    return 0; 
} 

回答

1

我認爲基本問題是你有派生類初始化基類的成員。如果您將受保護的成員設爲私有,並強制派生類將適當的值傳遞給基類構造函數,則它們必須正確構建自己。

如果只有基類的構造函數是

iDrawableObject(Graphic rG, Vector2f pos) 
    : renderGraphic(rG), positionOnScreen(pos) 
{ } 

派生類必須提供所需的信息。

另外,初始化在派生類基類成員,如

Circle(Vector2f _pos) 
    : 
    positionOnScreen(_pos) // member of iDrawableObject 
{  
} 

不反正工作。

+0

感謝Bo Persson,這有助於我澄清事情。 我是這樣避免這樣做的,因爲我想盡可能保持構造器的整潔(因爲在某些類中存在重要的「裝飾」調用,但我認爲這是實現它的唯一真正方法。 –