调用内部虚拟函数的c++函数

c++ Functions that call virtual functions inside

本文关键字:函数 c++ 虚拟 内部 调用      更新时间:2023-10-16

一直在努力更好地理解虚拟函数。为了便于论证,假设我有一个基类:

class Shape
{
protected:
    string _name;
    int _num;
public:
    Shape();
    virtual double CalcShape();
};

和2个较低级别:

class Rectangle : public Shape
{
private:
    double _height;
    double _width;
public:
    Rectangle();
    Rectangle(double, double);
    double GetHeight();
    double GetWidth();
    double CalcShape(double, double); //calculates rectangle
};
class Triangle : public Shape
{
private:
    double _side1;
    double _side2;
    double _side3;
public:
    Triangle();
    Triangle(double, double, double);
    double GetSide();
    double CalcShape(double, double, double); //calculates triangle
};

假设我还有一个叫做ShowCalc(Shape&);的函数。此函数调用内部的CalcShape()函数。

void ShowCalc(Shape& sh)
{
    return sh.CalcShape(); 
}

现在有没有一种方法可以让这个函数CalcShape()接受三角形的GetSide()函数以及矩形的GetHeight()GetWidth()的输入,就像三角形取3个参数,矩形取2个参数一样?

我在这里看到多个设计错误:

  • 不能将virtual方法与引用一起使用:引用指向指定类型的真实对象。动态调度不起作用,因为Shape&Shape,即使在初始化值时为其分配子类,由于对象切片,派生的所有内容都会被丢弃
  • virtual函数是指当子类中的重写方法具有特定实现时使用的函数。重写的方法具有与原始方法相同的签名。在您的情况下,Shape中有CalcShape(void)Rectangle中有CalcShape(double, double)。这不是覆盖,这是重载这是完全不同的事情。您可以提前使用C++11中的override关键字,以确保您正确地覆盖了虚拟方法
  • 如果基类上的实现没有意义(因为无法计算未知类型形状的面积),virtual方法应该是纯的。如果您有这个纯(= 0),编译器会警告您没有一个子类实际覆盖它

要获得您想要的内容,您需要在实现中使用成员变量,而不是通过调用传递它们,例如:

class Shape {
  virtual double calcArea() = 0;
}
class Rectangle : public Shape {
  private: 
    double width, height;
  public:
    virtual double calcArea() override { return width*height; }
}
Shape *shape = new Rectangle(10,20);
double area = shape->calcArea();