CPP多态与虚函数

[toc]

CPP多态与虚函数

印象中对于多态的理解是,通过父类指针调用类方法时,将根据指针指向的对象类型调用相应的类方法。今天我突然有了一个疑问,如果父类中有一个非虚函数调用了一个虚函数,并且在子类中对该虚函数进行了重写,那么通过子类对象或者基类指针调用该方法时,程序的行为会是什么样的呢?

带着这个疑问,我写了一个程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>

using namespace std;

class Shape
{
public:
virtual double area() { return 0.0; }
void show() { cout << "Area is: " << area() << endl; cout << hex << "Address is: " << this << endl; }
};

class Circle : public Shape
{
private:
double r = 0.0;

public:
Circle(double radius) : r(radius) {}
double area() { return 3.14 * r * r; }
};

int main(void)
{
Shape shape;
Circle circle(2.0);

shape.show();
circle.show();

Shape *pt = &circle;
pt->show();

return 0;
}

程序的运行结果如下:

1
2
3
4
5
6
Area is: 0
Address is: 0x61fe10
Area is: 12.56
Address is: 0x61fe00
Area is: 12.56
Address is: 0x61fe00

看来在基类内部调用虚函数也具有多态性。这种特性在开发中非常实用,与上述提到的通过父类指针调用类方法不同,实际应用开发过程中,很多操作是在类中通过多个类成员函数组合实现的,对于基类及其派生的子类,它们的类成员函数的实现可能是不同的,因此只需重写类成员函数,而对外的接口则直接使用从基类继承下来的版本,即不需要像下面这样重写一遍接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Shape
{
public:
virtual double area() { return 0.0; }
virtual void show() { cout << "Area is: " << area() << endl; }
};

class Circle : public Shape
{
private:
double r = 0.0;

public:
Circle(double radius) : r(radius) {}
double area() { return 3.14 * r * r; }
void show() { Shape::show(); }
};

area函数被非常多的接口函数调用时,有了这一特性的支持,编码效率将能大大得到提高。