当基类使用虚拟时,在类hieracrhy中使用virtual

fir*_*ush 1 c++ polymorphism

我不理解Stroustrup的A Tour of C++,第43和44页的继承示例.我复制了一个最小的例子来证明我的困惑:

#include <iostream>

class Shape {
public:
    virtual void draw() const = 0;
    virtual ~Shape() {};
};

class Circle : public Shape {
public:
    Circle(int p, int rr) : x{p}, r{rr} {}
    void draw() const { std::cout << "In Circle::draw()" << std::endl; }
private:
    int x;
    int r;
};

class Smiley : public Circle {
public:
    Smiley(int p, int r): Circle{p,r}, mouth(nullptr) {}
    ~Smiley() { delete mouth; }
    void draw() const { std::cout << "In Smiley::draw()" << std::endl; }

private:
    Shape* mouth;
};

int
main(int argc, char *argv[])
{
    Circle *smiley;
    smiley = new Smiley(3, 4);
    smiley->draw();

    Circle *circle;
    circle = new Circle(3, 4);
    circle->draw();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

令我困惑的是Circle :: draw不是虚拟的.我看到了,并认为这一定是一个错字.由于虚拟表示要查看定义的派生类,因此我不认为Smiley的绘制将从基本Circle引用中以多态方式调用.但是,我运行代码并获得以下输出:

In Smiley::draw()
In Circle::draw()
Run Code Online (Sandbox Code Playgroud)

请帮忙.这怎么可能?当Circle :: draw不是虚拟时,Smiley :: draw是如何从Circle*指针调用的?这难道不是需要声明派生类虚拟函数(如圈::平局)为进一步派生类的功能(如笑脸::平局)当一个基类层级结构中的是虚拟的(形状::平局)?

Nei*_*irk 11

Circle::draw实际上是虚拟的!这是因为Shape::draw是虚拟的.从基类覆盖虚函数时,该函数自动为虚函数,不需要关键字.我想提供虚拟关键字,以明确它是一个虚拟功能,但它是可选的.

在C++ 11中,您可以标记被覆盖的函数override,以确保它们实际上覆盖了虚函数.这可以防止错误.

void draw() const override
Run Code Online (Sandbox Code Playgroud)

  • @AdrianoRepetti是的. (2认同)
  • 哦该死的我没有看到`Shape`基类与`虚拟空画()!我的坏!!! (仅编辑为undownvote) (2认同)