[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
函数被非常多的接口函数调用时,有了这一特性的支持,编码效率将能大大得到提高。