class A {
public:
virtual void fun1() {}
virtual void fun2() {}
};
int main()
{
A a;
// 1.&a代表对象b的起始地址
// 2.(intptr_t*)&a 强转成intptr_t*类型,为了后面取b对象的一个指针宽度的字节,这是虚表指针
// 3.*(intptr_t*)&a 取一个指针宽度的字节,即vptr虚表地址
cout << "__vfptr地址:" << &a << endl;//带有虚函数的虚函数表指针的地址为类对象的起始地址
cout << "__vfptr指针变量的值也就是虚函数表(指针数组)的起始地址:" << (void*)*(intptr_t*)&a << endl;//偏移一个指针宽度
// 根据上面的解析我们知道*(intptr_t*)&b是vptr,即虚表指针.并且虚表是存放虚函数指针的
// 所以虚表中每个元素(虚函数指针)为(intptr_t *)*(intptr_t *)&a
// 这样强转后为了后面的一个指针宽度.所以*(intptr_t*)*(intptr_t*)&a就是虚表的第一个元素.即fun1()的地址.
// 那么接下来的取第二个虚函数地址也就依次类推. 始终记着vptr指向的是一块内存,
// 这块内存存放着虚函数地址,这块内存就是我们所说的虚表.
cout << "虚函数表第一个虚函数指针的地址:" << (void*)*(intptr_t*)*(intptr_t*)&a << endl;//再次偏移一个指针宽度得到虚函数表中第一个虚函数的地址
cout << "虚函数表第二个虚函数指针的地址:" <<(void*)*((intptr_t*)*(intptr_t*)&a+1) << endl;//通过虚函数表中第一个虚函数的地址的偏移量+1得到第二个虚函数的地址
system("pause");
return 0;
}
从虚函数表中获取虚函数地址
猜你喜欢
转载自blog.csdn.net/kingbrown1234/article/details/81201526
今日推荐
周排行