取虚表的内容

#include <iostream>
#include <typeinfo>

using namespace std;

class CFather
{
public:
	virtual void fun()
	{
		//cout << typeid(*this).name() << " " << "fun()" << endl;
		cout << "fun()" << endl;
	}

	virtual void show()
	{
		cout << "CFather  " << "show()" << endl;
	}
};

class CSon : public CFather
{
public:
	virtual void show()
	{
		cout << "CSon " << "show()" << endl;
	}
};

int main()
{
	CFather * fa = new CSon;
	//取虚表的内容
	// (int *) fa    在 fa 前面加上(int*) 是:将 CFather * 强转为(int *)指针,因为虚表的地址是对象的前四个字节里面,所以转换成(int *)指针,就是四个字节
	// *(int*) fa  在(int*)fa前面加上* 是 : 将虚表的地址的前四个字节的内容取出,这就是虚表的地址,*(int*)fa就是虚表的地址
	// (int*)(*(int*)fa) 将虚表的地址强转为(int*)类型,这是因为虚表就是一个数组,每一个数组元素就占四个字节(32位是四个,64位是8个)
	//                   
	// *((int*)(*(int*)fa) + 0) 获取虚表数组的第一个元素的内容,就是虚函数列表的第一个虚函数的地址,这里CFather的第一个虚函数是 void fun()
	//                      
	// *((int*)(*(int*)fa) + 1) 获取虚表数组的第二个元素的内容呢,就是虚函数列表的第二个函数地址,这里CFather的第二个虚函数是void fun(),因为是fa是指向子类的地址,
	//                            第二个虚函数void fun() 在子类中有重写,所以这里将是子类的 void fun()函数的地址

	typedef void(*p)(); //typedef 一个函数指针 为p
	//(p)(*((int*)(*(int*)fa) + 0)) //将虚函数列表里面的第一个函数地址,强转为函数指针
	// 函数指针调用函数,就是在指针后面加小括号 ()
	((p)(*((int*)*(int*)fa + 0)))(); //调用 fun()函数
	((p)(*((int*)(*(int*)fa) + 1)))();//调用 show()函数,注意是子类的show()函数

	//虚表的结尾
	int * p2 = (int*)*((int*)*(int*)fa + 2);//CFather只有两个虚函数,所以 + 2 就是到了虚函数列表的结尾,然后可以看到pp的内容是0x00000000,这里我用VS2008并不是这个,是一个随机的地址,用VS2013是这个
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值