当在基类中使用了关键字Virtual,就要使用滞后绑定,系统就会在编译时给每个类生成一张虚拟函数表,如上图,也就是一张虚函数指针表,这些指针指向每个虚函数的地址。而类的对象地址最前面是一个虚表指针,指向了类对应的虚表。运行时系统会根据虚表指针指向的虚函数指针来确定调用虚函数的哪个版本。 这就实现了一个接口,多种方法。如果不加关键字Virtual,系统在编译时就会使用早期绑定,它根据指针对象的类型来确定调用虚函数的哪个版本。所以下面的例子有无Virtual关键字的运行的结果就不同。
#include"stdafx.h" #include<iostream> using namespace std; class Base { public: virtual void VirtualFun() { cout<<"class Base!!\n"; } }; class Derived:public Base { public: void VirtualFun() { cout<<"class Derived!!"; } }; void mian() { Base *BasePtr, BaseObject; Derived DerivedObject; BasePtr = &BaseObject; BasePtr->VirtualFun(); BasePtr = &DerivedObject; BasePtr->VirtualFun(); }当无关键字Virtual时结果如下: class Base!! class Base!! ·BasePtr是基类对象指针,当不加关键字Virtual时,系统就会调用基类的VirtualFun(),所以第二行运行结果也是class Base!! 加上关键字Virtual: class Base!! class Derived!! 加上关键字后,系统就用之后绑定,运行时会根据虚表指针实际指向的虚函数指针来确定调用哪个函数, BasePtr = &DerivedObject;指针指向了派生类,所以第二行的运行结果就是class Derived!!。
讲的不对的请大佬指正本菜鸟^ _ ^。
