简体   繁体   English

虚拟继承中的重载虚拟函数

[英]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:但是当我将IsocelesTriangle Draw() IsocelesTriangleDraw(int) ,它开始给我这样的错误:

虚拟继承中的重载函数(在父类中是虚拟的)

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.当我将PolygonDraw()设为非虚拟时,此错误不会弹出并且程序成功运行(显然是以非多态方式)。 Why?为什么? What link does it ( virtual function in base class) have to do with the signature of Draw() in IsocelesTriangle ?它(基类中的virtual函数Draw()IsocelesTriangleDraw()签名有什么联系?

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 .我相信这个想法是,如果你不覆盖IsoscelesTriangle Draw (并且改变签名不再覆盖),你最终会在最终类IsoscelesTriangle得到 2个Draw函数,一个来自IsoscelesPolygon ,另一个来自Triangle ,并且都尝试覆盖Draw from Polygon The compiler finds it ambiguous.编译器发现它不明确。 Note that g++ spits out a more readable error:请注意, g++ 会吐出一个更具可读性的错误:

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 .虚拟继承只是确保基础对象Polygon不会在IsoscelesTriangle出现两次。 In your case, whenever you explicitly override Draw , the compiler hides the other 2 Draw s coming from Triangle and IsoscelesPolygon , so no more confusion.在您的情况下,每当您显式覆盖Draw ,编译器都会隐藏来自TriangleIsoscelesPolygon的其他 2 个Draw ,因此不再混淆。

PS: you'll find the same error even if you remove Draw completely from IsoscelesTriangle . PS:即使您从IsoscelesTriangle完全删除Draw您也会发现相同的错误。 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当我将 Polygon 中的 Draw() 设为非虚拟时,此错误不会弹出并且程序成功运行(显然是以非多态方式)

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).这里的想法是,现在每个TriangleIoscelesPolygon Draw声明为virtual ,所以基本上它们从一个干净的状态开始并重载函数Draw from Polygon (被标记为非虚拟)。 You then end up with 2 different Draw functions in IsoscelesTriangle , which are not trying to override the Draw from Polygon .然后,您最终会在IsoscelesTriangle获得 2 个不同的Draw函数,它们不会尝试覆盖来自PolygonDraw

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM