Catch_0x16
Catch_0x16

Reputation: 307

Calling overridden interface method in interface constructor

I've created an interface called 'iDrawableObject' that contains all of the drawing related methods/members for an object.

The interface also includes virtual methods such as 'decorate' in which derived classes can change the way in which they appear on screen.

I call the decorate method in the constructor of the iDrawableObject interface, but, as predicted it does not call the overridden method. This is because the constructor for the interface is run before that of the derived class and thus the method has not yet been overridden.

The alternative I have found to this predicament, is to manually call the overridden 'decorate' method in the constructor of the derived class. However this seems bad to me as it would be very easy to forget and it is an added 'dependency' so to speak.

My question is: What is the best way of having the overridden 'decorate' method called on the derived class without forcing the implementer to manually call it in the constructor of every derived class (It is safe to assume all classes that use the interface will need to call their own decorate implementation).

Thanks!

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;
}

Upvotes: 0

Views: 96

Answers (1)

Bo Persson
Bo Persson

Reputation: 92271

I think the basic problem is that you have derived classes initialize members of the base class. If you make the protected members private, and force the derived classes to pass proper values to the base class constructor, they will have to construct themselves properly.

If the only base class constructor is

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

the derived classes must provide the needed info.

Also, initializing a base class member in a derived class, like

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

doesn't work anyway.

Upvotes: 1

Related Questions