虚拟继承中的重载虚函数

时间:2015-01-24 03:41:35

标签: c++ inheritance polymorphism overloading

我的问题有点冗长。一旦你解决了整个问题,请回答它。

我已按如下方式实施钻石问题:

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

它工作得非常好并且由于虚拟继承而解决了Diamond问题。但是当我将IsocelesTriangle中的Draw()更改为Draw(int)时,它会开始给我这样的错误:

Overloaded Function (virtual in parent class) in Virtual Inheritance

当我将Polygon中的Draw()设置为非虚拟时,此错误不会弹出并且程序成功运行(显然是以非多态方式)。为什么?什么链接(基类中的虚函数)与IsocelesTriangle中的Draw()签名有关?

1 个答案:

答案 0 :(得分:4)

我认为,如果你没有覆盖Draw中的IsoscelesTriangle(并且更改签名不再覆盖),那么你最终会得到2 Draw个函数。最终课程IsoscelesTriangle,一个来自IsoscelesPolygon,另一个来自Triangle,并且都试图覆盖Draw中的Polygon。编译器发现它不明确。请注意,g ++会出现更易读的错误:

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

虚拟继承只是确保基础对象PolygonIsoscelesTriangle中没有出现两次。在您的情况下,无论何时显式覆盖Draw,编译器都会隐藏来自DrawTriangle的其他2 IsoscelesPolygon,因此不会产生混淆。

PS:即使您从Draw完全删除IsoscelesTriangle,也会发现相同的错误。无论如何,好问题,希望我做对了。


现在,关于问题的最后部分

  
    

当我将Polygon中的Draw()视为非虚拟

时,此错误不会弹出并且程序成功运行(显然是非多态的)   

这里的想法是,现在每个TriangleIoscelesPolygon都将Draw声明为virtual,所以基本上它们以干净状态开始并重载函数{{1}来自Draw(标记为非虚拟)。然后,您最终会在Polygon中找到2个不同的 Draw函数,这些函数不会尝试覆盖 IsoscelesTriangle Draw }}