父类中有虚函数,父类继承子类后:
1)有各自的虚表指针和虚表;
2)对于子类中未被重写的虚函数,在父子类各自虚表中存储的函数地址都是父类中的虚函数地址;
3)对于子类中被重写的虚函数,在父子类各自的虚表中存储的函数地址是不同的;
exp1---无覆盖时
#include <iostream> using namespace std;
class base { public: virtual void fun1() { cout <<"base::fun1()"<<endl; } };
class devise:public base { public: int d_i; };
int main() { typedef void(*FUN)(void); FUN pfun = NULL; //函数指针
base b; devise d;
cout <<"基类对象虚表指针的地址:"<<(int*)(&b)<< endl; cout <<"子类对象虚表指针的地址:"<<(int*)(&d)<<endl;//两者不同
cout <<"基类虚表地址:"<<(int*)(int*)(&b)<<endl; // cout <<"子类虚表地址:"<<(int*)(int*)(&d)<<endl; //两者不同
pfun = (FUN)*((int*)*(int*)(&b)); pfun(); //虚表中存储的第一个虚函数 pfun = (FUN)*((int*)*(int*)(&d)); pfun(); //两者相同,都是base::fun1();
cout <<"基类虚表中第一个虚函数地址:" <<(int*)*((int*)*(int*)(&b))<<endl; cout <<"子类虚表中第一个虚函数地址:"<<(int*)*((int*)*(int*)(&d))<<endl;//两者相同 }
exp2 ---覆盖时
#include <iostream> using namespace std; class base { public: virtual void fun1() { cout <<"base::fun1()"<<endl; } public: int b_i; };
class devise:public base { public: void fun1() { cout <<"devise::fun1()"<<endl; } int d_i; };
int main() { typedef void(*FUN)(void); FUN pfun = NULL; base b; devise d; cout <<"基类对象虚表指针的地址:"<<(int*)(&b)<< endl; cout <<"子类对象虚表指针的地址:"<<(int*)(&d)<<endl;//虚表指针的地址 cout <<"基类虚表地址:"<<(int*)(int*)(&b)<<endl; //父类虚表地址(虚表指针的内容) cout <<"子类虚表地址:"<<(int*)(int*)(&d)<<endl; //子类虚表地址 pfun = (FUN)*((int*)*(int*)(&b)); pfun(); pfun = (FUN)*((int*)*(int*)(&d)); pfun(); cout <<"基类虚表中第一个虚函数地址:" <<(int*)*((int*)*(int*)(&b))<<endl; cout <<"子类虚表中第一个虚函数地址:"<<(int*)*((int*)*(int*)(&d))<<endl;; }
exp3 ---包含覆盖和无覆盖时
#include <iostream> using namespace std; class base { public: virtual void fun1() { cout <<"base::fun1()"<<endl; } virtual void fun2() { cout <<"base::fun2()"<<endl; } public: int b_i; };
class devise:public base { public: void fun2() { cout <<"devise::fun2()"<<endl; } int d_i; };
int main() { typedef void(*FUN)(void); FUN pfun = NULL; base b; devise d; cout <<"基类对象虚表指针的地址:"<<(int*)(&b)<< endl; cout <<"子类对象虚表指针的地址:"<<(int*)(&d)<<endl;//虚表指针的地址 cout <<"基类虚表地址:"<<(int*)(int*)(&b)<<endl; //父类虚表地址(虚表指针的内容) cout <<"子类虚表地址:"<<(int*)(int*)(&d)<<endl; //子类虚表地址
pfun = (FUN)*((int*)*(int*)(&b)); pfun(); pfun = (FUN)*((int*)*(int*)(&b)+1); pfun(); pfun = (FUN)*((int*)*(int*)(&d)); pfun(); pfun = (FUN)*((int*)*(int*)(&d)+1); pfun(); cout <<"基类虚表中第一个虚函数地址:" <<(int*)*((int*)*(int*)(&b))<<endl; cout <<"子类虚表中第一个虚函数地址:"<<(int*)*((int*)*(int*)(&d))<<endl; cout <<"基类虚表中第二个虚函数地址:"<<(int*)*((int*)*(int*)(&b)+1)<<endl; cout <<"子类虚表中第二个虚函数地址:"<<(int*)*((int*)*(int*)(&d)+1)<<endl; }