标签:32位 fun 开始 func \n 知识点 指针 一个 函数地址
1.先介绍C++类的内存结构,大家可以看以下博客,觉得不错
https://blog.csdn.net/fenxinzi557/article/details/51995911
其中和本次相关的知识点是一个有虚函数的类的前4个字节是指向虚函数表首地址的指针_vfptr
2.下面开始说具体的求解过程
class AA {
public:
virtual void func1() { cout << "AA ::func1" << endl; }
virtual void func2() { cout << "AA ::func2" << endl; }
void func3() { cout << "AA::func3" << endl; }
};
typedef void(*Fun)(void); //函数指针
int main()
{
AA a;
// *****printf("虚表地址:%p\n", *(int *)&a); 解析*****:
// 1.&a代表对象a的起始地址
// 2.(int *)&a 强转成int *类型,为了后面取a对象的前四个字节,前四个字节是虚表指针
// 3.*(int *)&a 取前四个字节,即vptr虚表地址
// *****printf("第一个虚函数地址:%p\n", *(int *)*(int *)&a);*****:
// 根据上面的解析我们知道*(int *)&a是vfptr,即虚表指针.并且虚表是存放虚函数指针的
// 所以虚表中每个元素(虚函数指针)在32位编译器下是4个字节,因此(int *)*(int *)&a
// 这样强转后为了后面的取四个字节.所以*(int *)*(int *)&a就是虚表的第一个元素.
// 即f()的地址.
// 那么接下来的取第二个虚函数地址也就依次类推. 始终记着vfptr指向的是一块内存,
// 这块内存存放着虚函数地址,这块内存就是我们所说的虚表.
//
printf("虚表地址:%p\n", *(int *)&a);
printf("第一个虚函数地址:%p\n", *(int *)*(int *)&a);
printf("第二个虚函数地址:%p\n", *((int *)*(int *)(&a) + 1));
Fun pfun = (Fun)*((int *)*(int *)(&a)); //virtual func1();
printf("func1():%p\n", pfun);
pfun();
pfun = (Fun)(*((int *)*(int *)(&a) + 1)); //virtual func2();
printf("func2():%p\n", pfun);
pfun();
}
标签:32位 fun 开始 func \n 知识点 指针 一个 函数地址
原文地址:https://www.cnblogs.com/YachenLee/p/8973832.html