【VC++】虚函数 内存结构 - 第三篇(篇外篇)(类有无实体对象,对虚函数表的影响研究)

本文只是研究,并不一定正确,更不会很系统全面。若有错误,还请斧正!

先贴上 完整代码:

#include <IOSTREAM>		//原创:https://blog.csdn.net/maoyeahcom/
#include <Windows.h>	//转载请指明出处,请勿用于商业用途
using namespace std;	//仅用于研究,不权威,可能存在错误

class Base{
public:
	virtual void F(){	cout<<"Base::F()"<<endl;	}
	virtual void G(){	cout<<"Base::G()"<<endl;	}
};
class Derive:public Base{
public:	
	virtual void F(){	cout<<"Derive::F()"<<endl;	}
	virtual void G2(){	cout<<"Derive::G2()"<<endl;	}
};

void Test()	
{	//这个函数只是定义,都没有调用,但同样决定着 类有无实体对象

	//
	//这一块代码,试一条时,把其它行都注释掉(或删掉)
//	Base b;	//只定义了Base实体对象,没有子类实体对象,那么内存中也只有Base的虚函数表
// 	Derive d; //只定义了子类实体对象,那么 父类、子类的虚函数表,在内存中都有
// 	Derive *d;//只定义了子类指针,无实体对象, 内存中 无 虚函数表
// 	Derive *d = new Derive; //相当于还是有实体对象,内存中 有 虚函数表
// 	Derive *d = (Derive*)new Base; //内存中 只有 父类虚函数表
 	Base *b = new Derive; //内存中 有 父类子类 虚函数表
	//	
}

void *FindMemory(DWORD StartAdd,DWORD EndAdd,void *Data,DWORD DataSize)
{
	MEMORY_BASIC_INFORMATION minfo;
	while(StartAdd<EndAdd)
	{
		::VirtualQuery((void*)StartAdd,&minfo,sizeof(MEMORY_BASIC_INFORMATION));
		if(minfo.AllocationProtect)
			if(minfo.State==MEM_COMMIT||minfo.State==MEM_FREE)
			{
				char *s=(char*)StartAdd,*e=s+minfo.RegionSize;
				for(;s<e&&s+DataSize<=e;s++)
					if(memcmp(s,Data,DataSize)==0)
						return s;
			}
			StartAdd=(DWORD)minfo.BaseAddress+minfo.RegionSize;
	}
	return 0;
}

void main()
{
	int *pFind = (int*)FindMemory(0x0 , 0x0FFFFFFF, "Base::G()",strlen("Base::G()"));

	cout<<endl;	
}

再说下试验步骤:

在这里插入图片描述
这一块代码,每一行都试一下(按上面的步骤):
//
//这一块代码,试一条时,把其它行都注释掉(或删掉)
// Base b; //只定义了Base实体对象,没有子类实体对象,那么内存中也只有Base的虚函数表
// Derive d; //只定义了子类实体对象,那么 父类、子类的虚函数表,在内存中都有
// Derive *d;//只定义了子类指针,无实体对象, 内存中 无 虚函数表
// Derive *d = new Derive; //相当于还是有实体对象,内存中 有 虚函数表
// Derive d = (Derive)new Base; //内存中 只有 父类虚函数表
Base *b = new Derive; //内存中 有 父类子类 虚函数表
//
懒得试验的,可以直接看后面注释(即我试验的结果),下面列出每一种试验的截图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在本文结束前,我也还是来介绍下自己吧。我从03年初学编程,一直到现在都在做软件开发方面的事,做过VC++、VB/Delphi/C++Builder、C#/Asp.Net、Java、Web前后端、数据库、服务器端、客户端、js、lua、Flash AS、cocos2dx/Unity3d……都有接触过,甚至做过很长一段时间的运营、产品策划、美工、客服、线下推广员、公司经理 多职务……技术只是一种工具,用来实现业务需求,所以最大的特长是逻辑思维、挖掘业务需求、强化用户体验、快速的产品实现,最自以为豪的,我做过的很多产品,很稳定,bug极少(当然也出现过没考虑周全的漏洞在所难免但总体上也还算少),有很多独立开发的游戏运营到现在还在稳定的运行。不是技术极客,而是业务需求带动技术的学习研究,所以也不怎么挑语言,编程语言大体上也都是相通的,底层原理也有很多类同的地方。所以缺点从不敢说精通哪一门语言。遇到小工具、小需求的订制实现,我个人最喜欢的还是用VC6,简洁干净,编译出来的东西 体积小,速度快,占CPU内存小。当然实际工作中,还是随项目。欢迎大家和我交流,我的QQ是:七6.肆-陆_柒-4`7_四.
生活中的我,热爱 街舞、飙车、花式游泳、游戏一条命通关……极限运动,我抖音号(一不小心玩出花样)是:1917940952

内存中找到的那个字符串,既不是虚函数,也不是虚函数表,只是虚函数体内写的打印字符串。这虽然不是权威的确定内存中有无虚函数的方法,但却是一种思路,两种不同表现的对比。
此文的阅读者,假设是不懂反汇编知识,纯用C++知识,探讨内存里的东西。如果你懂反编译,那此文就是小儿科,函数地址与内存关系了如指掌。
如果你有更好的思路或方法,还请指教,感谢不尽。

(转载时请注明作者和出处。未经许可,请勿用于商业用途)
原创出处:https://blog.csdn.net/maoyeahcom/article/details/108870301

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值