多态-虚函数表
单个类的虚函数表
class Father
{
public:
virtual void func1()const {
cout << "Father::func1" << endl;//把实现和成员函数写在一起好测试
}
virtual void func2()const {
cout << "Father::func2" << endl;
}
virtual void func3()const {
cout << "Father::func3" << endl;
}
void func4()const{
cout<<"Father::func4"<<endl;
}
public://都定义成public是为了更好的进行测试
int x = 200;
int y = 300;
static int z;
};
图一*
图二:
从第一张图可以看出用virtual定义的func1、func2、func3不会占用该对象的内存(只是会多出一个我们没有定义的一个指针),该指针是指向虚函数表的起始地址。
利用-》int* vptr = (int*)*(int*)(&father);把虚函数表指针vptr单独取出来
从图二中可以知道:虚函数表中存储的是每个虚函数的地址,每个地址与虚函数是相互对应的,利用函数指针来调用虚函数。
定义函数指针:typedef void(*func_t)(void);《=返回类型为void形参为空
#利用vptr指针的偏移来调用各个虚函数(vptr+0),(vptr+1),(vptr+2)
注意的一个点:
int* vptr = (int*)*(int*)&father;
它的用途是用来获取32位下C++ 对象的虚函数表的地址,那么从这个定义我们可以看出,vptr 就是int 类型的指针变量, 指针+1 得到的地址值并不是简单的把指针地址加上一个字节,而是加上1个指针类型所占的字节数,即: vptr+1 = vptr + 1*sizeof(int) , 在这里int 类型是4 ,那么 vptr +1 就是在现在地址值的基础上增加4个字节。
例如:
vptr 的值是 0x10000 , vptr +1 就是 0x10000+1x4 = 0x10004