深入浅出MFC:MFC中的的RTTI实现

在了解了MFC的基本运行的流程之后,让我们再来看看一个特殊的问题:如何在运行的过程中动态地保存一个对象的类型信息并判断得到其类型

虽然在很早之前,C++就已经原生的实现了RTTI特性,只需要通过使程序包含该头文件<typeinfo.h> ,然后使用typeid 运算符即可直接获取对象的类型,但是对于更早出现的MFC,一开始没有RTTI,所以MFC只好自身内部实现了一套“运行时自动类型识别的机制”。

对于RTTI的实现,该如何设计呢?对于一种颜色,如果想要知道他的RGB成分,没有供你查找的RGB表可以做到么?对于一个没学过英语的人,一个英语单词不通过词典能知道它的意思么?对于对象的类型,也是一样的,所以我们需要建立这样一个数据结构来保存我们所有的类型,而且我们需要在对象建立起来的时候就实现该类型的记录,对于数据结构的选择这里我们跟随侯俊杰先生的想法,选择链表,这有利于我们快速的遍历查询。

在我们建立这样一条链表之前,我们需要预先设计一个用来储存相关类型信息的单元结构:

这里引用《深入浅出MFC》中的一段实现定义:

struct  CRuntimeClass
{
	LPCSTR m_lpszClassName;  // LOCSTR = char*
	int m_nObjectSize;
	UINT m_wSchema; //加载类的架构数字 UNIT = int
	CObject* (PASCAL* m_pfnCreateObject)();
	CRuntimeClass* m_pBaseClass;

	//运行类型个体被链接到一张单一的链表上
	static CRuntimeClass* pFirstClass;  //链表头
	CRuntimeClass* m_pNextClass;        //通过此指针链接被注册的类
};

我们的数据单元中主要储存以下信息:类型的名字,类型的大小,类型的编号(全部被指定为0xFFFF,说实话也不知道这么翻译对不对),一个全局的静态的表头,往往指向末端的子类,一个指向该类型基类的单元的指针,。一个指向下一个类型单元的指针(主要用于结构的链接与遍历查找),还有一个奇奇怪怪的函数指针,其他的以后再说,我们目前只需要关注:类名称,链表的Next指针,以及链表的全局First指针即可。

如果要做到运行时的类型识别,那我们还是需要在每个类的里面塞进我们的这个保存有类型信息的结构,这样在判断某实例类型的时候才可以有据可查,对于这个结构的添加,MFC这里采用了这样一种方式:

#define DECLARE_DYNAMIC(class_name) \
public: \
		static CRuntimeClass class##class_name; \
		virtual CRuntimeClass* GetRuntimeClass() const;
声明了这样一个宏,其实内容很简单,宏的内容就是声明一个对应类的局部变量和对应一个公有方法,其中局部变量的名字随绑定类型而动态变化,该变量实际保存的就是之前的藏有类型信息的结构,可是光有这样的结构还不行,我们还需要对这样的结构的内容进行填充并且将类型之间全部链接起来,建立起他们本该由的联系

在这里再先看一个有趣的结构:

struct AFX_CLASSINIT
{
	AFX_CLASSINIT(CRuntimeClass* pNewClass);
};
这个结构体本身无其他含义,重点在于他的构造函数上,其构造函数内容如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值