MFC解密(3) 动态创建

本文详细解析MFC中动态创建对象的过程,涉及DECLARE_DYNCREATE、IMPLEMENT_DYNCREATE宏,以及CRuntimeClass如何实现对象的创建。通过CRuntimeClass的Load和CreateObject函数,动态创建对象并管理类的链表。同时强调了在MFC中使用动态创建时,需要无参构造函数以及DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE宏的使用。

关键字:

DECLARE_DYNCREATE

IMPLEMENT_DYNCREATE

 

 

1. MFC通过上面2个宏为我们包装了 对象 的创建过程

 

可见,DECLARE_DYNCREATE实际上包含了2步

1. DECLARE_DYNAMIC    实现RTTI

2. CreateObject()           实现对象动态创建

 

2. 实际上动态创建也是通过CRuntimeClass来实现的

接上段程序

 

pfnNew作为参数传给CRuntimeClass 对象,CRuntimeClass中有一个函数指针来记录我们自己类的创建函数的地址

CObject (* m_pfnCreateObject)();

这样我们只需要调用CRuntimeClass::m_pfnCreateObject就可以实现对我们自己类的创建。

 

3. CRuntimeClass为我们创建我们自己类对象的实际过程

CRuntimeClass里有2个辅助函数帮助我们进行创建

 

 

因为MFC层次结构是树状的,并不是直线的。如果我们只有一个m_pBaseClass指针,它只会沿着基类上去,会漏掉其它分支。在动态创建时,必需要检查整个链表,看有多少个要动态创建的对象,即是说要从表头(pFirstClass)开始一直遍历到表尾(m_pNextClass=NULL),不能漏掉一个CRuntimeClass对象。

所以每当有一个新的链表元素要加入链表的时候,我们要做的就是使新的链表元素成为表头,并且m_pNextClass指向原来链表的表头,即像下面那样(当然,这些不需要我们操心,是RTTI宏帮助我们完成的):

pNewClass->m_pNextClass=CRuntimeClass::pFirstClass;//新元素的m_pNextClass指针指向想加入的链表的表头。

 

 

CRuntimeClass::pFirstClass=pNewClass;//链表的头指针指向刚插入的新元素。

 

 

好了,有了上面的链表,我们就可以分析动态创建了。

有一了张有类名,函数指针,动态创建函数的链表,我们就可以知道应该按什么步骤去动态创建了:

1、获得一要动态创建的类的类名(假设为A)。

2、将A跟链表里面每个元素的m_lpszClassName指向的类名作比较。

3、若找到跟A相同的类名就返回A所属的CRuntimeClass元素的指针。

4、判断m_pfnCreateObject是否有指向创建函数,有则创建对象,并返回该对象。代码演示如下(以下两个函数都是CRuntimeClass类函数):

 

4. RUNTIME_CLASS

该宏帮助我们通过类名得到类的CRuntimeClass对象的名字

通过这个宏我们可以直接使用

RUNTIME_CLASS(class_name)->createObject();

来创建对象

 

5. 实际使用

1、定义一个不带参数的构造函数(默认构造函数);因为我们是用CreateObject()动态创建,它只有一条语句就是return new XXX,不带任何参数。所以我们要有一个无参构造函数。

2、类说明中使用DECLARE_DYNCREATE(CLASSNMAE)宏;和在类的实现文件中使用IMPLEMENT_DYNCREATE(CLASSNAME,BASECLASS)宏;这个宏完成构造CRuntimeClass对象,并加入到链表中。

3、使用时先通过宏RUNTIME_CLASS得到类的RunTime信息,然后使用CRuntimeClass的成员函数CreateObject创建一个该类的实例。

4、CObject* pObject = pRuntimeClass->CreateObject();//完成动态创建。

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值