OOP的核心思想是多态性(polymorphism)。其含义是“多种形态”。我们把具有继承关系的多个类型称为多态类型。引用或指针的静态类型和动态类型不同这一事实正是C++语言支持多态性的根本所在。
多态性:当用于面向对象编程的范畴时,多态性的含义是指程序能通过引用或指针的动态类型来获取类型特定行为的能力。
多态性在C++中是通过虚函数来实现的。
首先我们先来强调几组概念:
静态多态和动态多态、静态联编和动态联编、静态类型和动态类型
1. 静态类型和动态类型
静态类型——在编译时是已知的,它是在变量声明时的类型或表达式生成的类型。
动态类型——对象在运行时的类型。引用所引对象或指针所指对象的动态类型可能与该引用或指针的静态类型不同。基类的指针或引用可以指向一个派生类对象,在这种情况下,静态类型是基类的引用(或指针),而动态类型是派生类的引用(或指针)。
Devese d;
Base *pb = &d; //静态类型是基类的指针,动态类型是派生类的指针
2. 静态联编和动态联编
静态联编——也称静态绑定或早期联编,比如之前提到的函数重载,运算符重载。它是在编译过程汇总进行的联编。
动态联编——也称动态绑定,直到运行时才知道到底调用函数的哪个版本。在C++语言中,动态绑定的意思是在运行时根据引用或指针所绑定对象的实际类型来选择执行虚函数的某一个版本。
3. 静态多态和动态多态
(下图中“多态多态”应该是“动态多态”,实在抱歉)
虚函数
虚函数——用于定义类型特定行为的成员函数。通过指针或引用对虚函数的调用直到运行时才被解析,依据是引用或指针所绑定对象的实际类型。
虚函数的用法格式:
virtual 函数返回类型 函数名 (参数列表) {函数体}
当我们使用基类的指针或引用基类中定义的一个函数时,我们并不知道该函数真正作用的对象是什么类型,因为它可能是一个基类的对象也可能是一个派生类的对象。如果该函数是虚函数,则直到运行时才会决定到底执行哪个版本,判断的依据是引用或指针所绑定对象的实际类型;反之,如果是非虚函数,对非虚函数的调用在编译时进行绑定。
类似的,通过对象的函数调用也在编译时绑定。对象的类型是确定不变的,我们无论如何都不可能令对象的静态类型和动态类型不一致。因此,通过对象进行的函数调用将在编译时被绑定到该对象所属类中的函数版本上。
——摘自《C++ Primer》
看下面一段代码:
class Father
{
public:
void fun()
{