首先来看看多态的定义,这里引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。多态在C++中是通过虚函数(virrtual)实现的。C++中,实现多态有以下方法:虚函数,抽象类,重载,覆盖,模板。面向对象最强大的地方就是多态,而不是继承。
C++支持两种多态:
1. 编译时多态:通过重载函数实现;
2. 运行时多态:通过虚函数实现。
编译时多态比较简单,下面主要谈谈运行时多态。
-------------------------------------------------------------------------------------------------------------------------------------------
基类类型的指针可以指向任何基类对象或派生类对象,指向哪个对象就调用相应对象的函数。
需要注意的是:1.当声明了基类的一个成员函数为虚函数后,那么即使该成员函数没有在派生类中被显式地声明为虚函数,但它在所有派生类中也将自动称为虚函数;2.如果虚函数在类声明外定义,关键字仅在函数声明时需要,不需在函数定义中使用virtual关键字;3.
最好将所有的声明前加上virtual关键字,以避免用户产生疑惑。
来看个例子:
#include <iostream> using namespace std; class parent { public: parent(){} void out() { cout << "1" << endl; } virtual void fun() { cout << "2" << endl; } }; class child:public parent { public: child(){} void out() { cout << "3" << endl; } void fun() { cout << "4" << endl; } }; int main() { parent par; child chi; parent* p = ∥ p->out(); p->fun(); p = χ p->out(); p->fun(); if(p != NULL) delete p; child* q =(child*)∥ q->out(); q->fun(); if(q != NULL) delete q; return 0; }
结果是:
让我们来分析一下:
第一部分p->out()和p->fun()很好理解,基类指针指向基类对象,调用的都是基类本身的函数,结果是1、2;
第二部分p->out()和p->fun()是基类指针指向子类对象,这就是多态的用法。p->out()是基类指针指向固定偏移量(相对于基类)的函数,输出结果是1;p->fun()是基类指针指向虚函数列表,根据指向的对象不同,通过虚函数列表找到相应的函数,这里找到的是子类的fun()函数地址,输出结果是4;第三部分p->out()是子类指针指向固定偏移量(相对于子类)的函数,输出结果是3;p->fun()是子类指针指向虚函数列表,根据指向的对象(这里是基类)不同,输出结果是2。