栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++如何拿到虚表指针(指向虚函数数组的指针)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++如何拿到虚表指针(指向虚函数数组的指针)

编译器给每个对象添加了一个隐藏成员,这个成员指向了对象的虚函数数组,对象的子类会根据有没有重新定义特定虚函数来决定更新还是复制该特定函数的虚函数地址,存在虚函数数组里.

这就是虚函数的原理.

那么怎么把这个指针拿到呢?

请看下面的代码

class Father
{
public:
	 virtual void fun1()
	{
		cout << "Father fun()" << endl;
	}
};
class son:public Father
{
public:
	virtual void fun2()
	{
		cout << "son fun2()" << endl;
	}
	virtual void fun3()
	{
		cout << "son fun3()" << endl;
	}

};

如图所示

 在visual studio的编译器下虚表指针就在对象内存空间的首个四字节地址(32位编译环境下),我们知道指针的大小都是一样的,所以我们可以用强制类型转换把对象的地址转换int*类型(四字节类型)来拿到这个指针

如下代码

son* p = new son;
cout < 

 

 

这样子 就拿到了虚表指针但是类型不对,数值是一样的(你可以自己在vs的dubug监视窗口看到)

让我们再用这个指针来调用虚函数

如下代码

typedef void(*P)();
	int v_ptr = *(int*)pson;
	int  fun = *(int*)v_ptr;
    P Pfun= (P)fun;
    Pfun();

思路是拿到虚表指针以后也就是v_ptr,此时类型是int ,他的数值就是虚表的地址,我们再将它转成int*然后解引用*(int*)v_ptr,这样就拿到了这个v_ptr指向的四字节也就是第一个虚函数Father::fun1的地址的数值fun 注意此时的类型是int

然后再将它转成对应类型的函数指针Pfun;

最后调用

如图

 同理我们也可拿到fun2和fun3

完整源代码

#include
using namespace std;
class Father
{
public:
	 virtual void fun1()
	{
		cout << "Father fun()" << endl;
	}
};
class son:public Father
{
public:
	virtual void fun2()
	{
		cout << "son fun2()" << endl;
	}
	virtual void fun3()
	{
		cout << "son fun3()" << endl;
	}

};
int main()
{
	son* pson = new son;
	cout < 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/997605.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号