直接看代码
#include <iostream>
#include <stdio.h>
using namespace std;class person
{
public:virtual void name(){cout<<"A::name"<<endl;}private:virtual void sex(){cout<<"A::sex"<<endl;}
};class student : public person
{
public:virtual void name(){cout<<"B::name"<<endl;}virtual void address(){cout<<"B::address"<<endl;}private:virtual void ID(){cout<<"B::ID"<<endl;}
};typedef void (*Fun)(void);//定义一个函数指针int main()
{student stu;for(long i = 0; i < 4; i++){Fun p = (Fun)*((long*) * (long*)(&stu)+i);p();}/***(long*)(&stu) 根据对象的虚函数表指针找到对应的虚函数表,指向虚函数表的首地址*((long*) *(long*)(&stu)+i) 对虚函数表的函数进行偏移调用(虚函数表中的函数也是一个个的指针,指向代码区中存放函数的地方)
*/return 0;
}
如图:
person类的虚函数表
student类的虚函数表
student派生类因为重写基类的name()函数,所以虚函数表指向重写后的自己的name()
结果:
总结:
只要能拿到对象的虚函数指针,就能找到对应的虚函数表,就可以调用虚函数表的函数