虚拟抽象方法的语义是什么?

时间:2017-12-09 13:08:05

标签: c++ inheritance

根据用户 Steve314 Why do we need virtual functions in C++?的答案的引用:

  

使用“虚拟”,您将获得“后期绑定”。使用该方法的哪个实现在运行时根据指向对象的类型决定 - 它最初构造为什么。根据指向该对象的指针类型,这不一定是您的想法。

我偶然发现了以下例子:

class Shape
{
    std::string name;
    friend std::ostream& operator<<(std::ostream&, const Shape&);
public:
    Shape(const std::string&);
    virtual double circumference() = 0; 
    virtual ~Shape() {}
protected:
    virtual void print(std::ostream&) const;
};

在从Shape继承的类中(例如Circle,Square ...),将覆盖虚函数。圆周()方法也是如此。

我的问题如下:如果circum()是一个无法调用的抽象方法(因为Shape是一个抽象类),为什么我们将它作为一个虚函数而不是简单地将它保留为抽象并像往常一样覆盖它在派生类中?

如果我理解正确,我们会创建一个方法 virtual 以确保“后期绑定”。例如。如果我们有以下代码块:

Shape *circle = new Circle();
double circ = circle->circumference();

使circum()虚拟我们确保将调用我们的指向对象的类类型的方法,而不是“声明”类型的方法(这里我们要调用Circle类的方法) )。

因此,如果以任何方式调用类Shape的circum()会导致编译时错误(使其无法发生),为什么我们将其设为虚拟而不仅仅是抽象?

1 个答案:

答案 0 :(得分:4)

附加virtual的{​​{1}}方法是抽象方法的定义。没有= 0关键字的抽象方法就没有。

virtual

这只是一个语法错误。非double circumference() = 0; 方法必须有一个定义。它不是抽象的,而是virtual

这样想:

  1. 该方法是否需要后期绑定,以便调用的确切实现在运行时会有所不同?如果是,请将其标记为= 0
  2. 如果它是virtual,基类是否想要提供默认实现?如果没有,请添加virtual
  3. 如果没有第1步,您就无法执行第2步。