【问题标题】:understanding virtual function理解虚函数
【发布时间】:2015-04-30 23:33:27
【问题描述】:
// multiple inheritance
#include <iostream>
using namespace std;

class Polygon {
  protected:
    int width, height;
  public:
    Polygon (int a, int b) : width(a), height(b) {}
    virtual int area()=0;
    virtual void print(){
        cout << "area = " << area() << endl;
    };
};



class Rectangle: public Polygon{
  public:
    Rectangle (int a, int b) : Polygon(a,b) {}
    int area () { return width*height; }
    void print(){
        cout << "area = " << area() << endl;
    };
};

class Square: public Rectangle{
  public:
    Square (int a, int b) : Rectangle(a,b) {}
    int area () { return width*height/2; }
};

int main () {
  Square sq (4,5);
  sq.print ();
  return 0;
}

在这个函数中,print 调用 Square(不是 Rectangle)的 area()。为什么?由于 Rectangle 中的 area() 不是虚拟的,它应该从 Rectangle 中调用 area()。最终结果是 10。据我说应该是 20。

【问题讨论】:

  • 正方形的面积是从什么时候开始的width*height/2???

标签: c++ inheritance


【解决方案1】:

由于Rectangle中的area()不是虚拟的,它应该从Rectangle调用area()

它实际上是virtual,因为它在基类中被声明为virtual。该属性会自动转移到继承类的成员函数声明中。

参见标准,虚拟函数 [class.virtual](强调我的):

如果在 Base 类和 Derived 类中声明了虚成员函数 vf直接或间接派生 来自 Base,具有相同名称、参数类型列表 (8.3.5)、cv-qualification 和 refqualifier 的成员函数 vf (或不存在相同)作为 Base::vf 被声明,则 Derived::vf 也是虚拟的(无论是否 如此声明),它覆盖 Base::vf


旁白。从矩形派生出一个正方形可以是problematic,因为它违反了里氏替换原则。

【讨论】:

  • 是否应该从square 调用area()
  • @StraightLine 嗯,是的。这就是我要说的?
  • @πάνταῥεῖ 你是说“它应该从Rectangle 调用area()
  • @StraightLine 不,这个答案解释了为什么它从Square 调用area() 而不是Rectangle
  • @StraightLine 所有area 函数都是虚函数,因此应该调用Squarearea
猜你喜欢
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多