Overloaded Virtual Function in Virtual Inheritance

北慕城南 提交于 2019-12-10 21:05:49

问题


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:

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 it (virtual function in base class) has to do with the signature of Draw() in IsocelesTriangle?


回答1:


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.



来源:https://stackoverflow.com/questions/28122037/overloaded-virtual-function-in-virtual-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!