我不理解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)