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

时间:2013-11-29 19:56:40

标签: c++ virtual-functions

一直在努力提高对虚拟功能的理解。为了论证,我说我有一个基类:

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()接受Triangle的GetSide()函数和Rectangle的GetHeight()GetWidth()的输入,看看Triangle如何处理3参数和矩形需要2?

1 个答案:

答案 0 :(得分:2)

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

  • 您不能将virtual方法与引用一起使用:引用指向该指定类型的实际对象。动态分派不起作用,因为Shape&Shape,即使在初始化值时为其分配子类,由于object slicing,所有派生的内容也会被丢弃。
  • virtual函数用于在子类中的重写方法具有特定实现时使用。重写方法具有与原始方法相同的签名。在您的情况下,CalcShape(void)中的ShapeCalcShape(double, double)中的Rectangle。这不是覆盖,这是重载,这是完全不同的事情。您可以在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();