从虚函数表中获取虚函数地址

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