本文共 1472 字,大约阅读时间需要 4 分钟。
虚函数是实现多态是通过维护一张虚函数表来实现的。
在类对象的头4个字节中,有一个指向这个虚函数表的指针,我们称为Vptr;
写一个类AA
class AA{public: virtual void F1() { cout << "AA:f1" << endl; } virtual void F2() { cout << "AA:f2" << endl; } virtual void F3() { cout << "AA:f3" << endl; }};
AA中有虚函数, 那么就有一张虚函数表;我们可以把AA 类对象的头4个字节拿出来,找到这张表
类对象: AA aa;
函数指针
typedef void(*FUN)();FUN pFun;
得到vptr的地址: (int*)&aa
得到虚表的地址:*(int*)&aa)
得到表中第一个函数地址: (int*)(*(int*)&aa)
取表中函数指针:(*(int*)(*(int*)&aa))
(对上面那个进行引用)
转成函数指针,供调用:
pFun = (FUN)(*(int*)(*(int*)&aa)); pFun(); //调用了AA的F1函数
当有类BB继承AA时,若BB中重写了AA的虚函数,那么就把虚表中的函数覆盖成自己的;
那么在调用时就会调用BB的F2函数;class AA{public: virtual void F1() { cout << "AA:f1" << endl; } virtual void F2() { cout << "AA:f2" << endl; } virtual void F3() { cout << "AA:f3" << endl; }};class BB:public AA{public: virtual void F2() { cout << "BB:f2" << endl; }};int main(){ AA aa; typedef void(*FUN)(); FUN pFun; //F1 pFun = (FUN)(*(int*)(*(int*)&aa)); pFun(); //F2 pFun = (FUN)(*((int*)(*(int*)&aa)+1)); pFun(); //F3 pFun = (FUN)(*((int*)(*(int*)&aa) + 2)); pFun(); cout << "-----------------------------------" << endl; //父类的指针指向子类的对象 AA * pA = new BB; //F1 pFun = (FUN)(*(int*)(*(int*)pA)); pFun(); //F2 pFun = (FUN)(*((int*)(*(int*)pA) + 1)); pFun(); //F3 pFun = (FUN)(*((int*)(*(int*)pA) + 2)); pFun(); system("pause"); return 0;}