Search code examples
c++inheritancepolymorphismoverloading

Overloaded Virtual Function in Virtual Inheritance


My question is bit lengthy. Kindly answer it only once you go through the whole problem.

I have implemented the Diamond Problem as follows:

class Polygon
{

protected:
    int sides;

public:

    Polygon()
    {
        cout << "Polygon's Default Constructor being called." << endl;
    }

    Polygon(int a)
    {
        cout << "Polygon's parameterized Constructor being called." << endl;
        sides = a;
    }

    void virtual Draw()
    {
        cout << "Polygon being drawn." << endl;
    }

    virtual ~Polygon()
    {
        cout << "Polygon's Destructor being called." << endl;
    }

};


class Triangle : virtual public Polygon
{
    int Angles[3];
public:
    Triangle()
    {
        cout << "Triangle's Default Constructor being called." << endl;

    }

    Triangle(int a)
    {
        cout << "Triangle's parameterized Constructor being called." << endl;
        sides = a;
    }

    Triangle(int a, int b) : Polygon(a)
    {
        cout << "Triangle's double parameterized Constructor being called." << endl;
        //sides = a;
    }


    void virtual Draw()
    {
        cout << "Triangle being drawn." << endl;
    }

    ~Triangle()
    {
        cout << "Triangle's Destructor being called." << endl;
    }

};

class IsoscelesPolygon : virtual public Polygon
{
    void virtual Draw()
    {
        cout << "Isosceles Polygon's Draw Called." << endl;
    }
};

class IsoscelesTriangle : public Triangle, public IsoscelesPolygon
{

    void Draw(int )
    {
        cout << "Isoceles Triangle's Draw() Called." << endl;
    }
};

It works perfectly fine and resolves the Diamond Problem due to virtual inheritance. But when I change Draw() in IsocelesTriangle to Draw(int), it starts giving me error like this:

Overloaded Function (virtual in parent class) in Virtual Inheritance

This error doesn't pop up and program successfully runs (in non-polymorphic way obviously) when I make the Draw() in Polygon as non-virtual. Why? What link does it (virtual function in base class) have to do with the signature of Draw() in IsocelesTriangle?


Solution

  • I believe the idea is that if you don't override Draw in IsoscelesTriangle (and changing the signature is not overriding anymore), you end up with 2 Draw functions in the final class IsoscelesTriangle, one from IsoscelesPolygon and other from Triangle, and both try to override the Draw from Polygon. The compiler finds it ambiguous. Note that g++ spits out a more readable error:

    error: virtual function 'Polygon::Draw' has more than one final overrider in 'IsoscelesTriangle'
    

    The virtual inheritance just ensures that the base object Polygon is not appearing twice in IsoscelesTriangle. In your case, whenever you explicitly override Draw, the compiler hides the other 2 Draws coming from Triangle and IsoscelesPolygon, so no more confusion.

    PS: you'll find the same error even if you remove Draw completely from IsoscelesTriangle. Good question anyway, hope I got it right.


    Now, regarding the last part of your question

    This error doesn't pop up and program successfully runs (in non-polymorphic way obviously) when I make the Draw() in Polygon as non-virtual

    The idea here is that now each Triangle and IoscelesPolygon declare Draw as virtual, so basically they start with a clean state and overload the function Draw from Polygon (which was marked as non-virtual). You then end up with 2 different Draw functions in IsoscelesTriangle, which are not trying to override the Draw from Polygon.