现在开始学习MFC的人,如果参考侯先生的"深入浅出",很有可能会碰到一些问题:现在的MFC和当年的MFC,版本已经不同,很多实现方式也变了。我的目的,是想把一些主要的不同拉出来,给各位同好共享。
说得不对的地方,还请各位达人指正!
第一点:查看DECLARE_DYNCREATE宏之后发现,struct CRuntimeClass中已经不存在m_pFirstClass了。另外一点就是m_pNextClass的赋值也都改变了。在IMPLEMENT_DYNAMIC以及IMPLEMENT_DYNCREATE中,甚至都不再赋值了。
说明:具体的改变不赘述,我想做个“改变原因及后果”分析:
首先谈谈各个变量的作用:
m_pNextClass的作用,把所有的类串起来;
m_pBaseClass的作用,把上下级串起来;
m_pFirstClass的作用,提供一个总的“型录网”入口;
动态生成的时候,通过m_pFirstClass入口,然后通过m_pNextClass遍历,一个个比较就能得到需要的类的类型定义,然后就可以new了。
通过m_pFirstClass入口,m_pBaseClass遍历,可以得到所有上级的信息。
显然IsKindOf并不需要知道全部的类信息,而入口只要自己的CRuntimeClass变量就可以,所以DYNAMIC完全可以不要m_pNextClass以及m_pFirstClass了。
对于动态生成而言,没有了m_pFirstClass,入口和DYNAMIC一样,遍历方式肯定也一样了,所以:
非序列化的动态生成只能限于上下级之内了,也就是说,你必须要提供一个入口,然后逐级而上,然后。。。;
然而在序列化的动态生成中,上述方式显然无法完成工作,因此现在MFC的做法,是把这么一个总入口改为一个隶属于“模块状态”的链表中,因此我们看到原来的简单而直接的AFX_CLASSINIT构造函数,修改为:
struct AFX_CLASSINIT
{ AFX_CLASSINIT(CRuntimeClass* pNewClass) { AfxClassInit(pNewClass); } };
而:
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
pModuleState->m_classList.AddHead(pNewClass);
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
}
(有兴趣可以再跟进去看看链表的实现)
这样一来,这个原来的“类别型录网”建立起来,只不过更加隐蔽一点而已。去除了m_pFirstClass,改为m_classList代替,m_pNextClass还在,不过已经只有在序列化的生命和实现中才存在了。
阅读(2026) | 评论(1) | 转发(1) |