Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1674139
  • 博文数量: 20
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 3272
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-04 09:45
文章分类

全部博文(20)

文章存档

2011年(3)

2010年(1)

2009年(1)

2008年(15)

我的朋友

分类: WINDOWS

2008-07-16 13:48:22

现在开始学习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) |
给主人留下些什么吧!~~

ytfrdfiw2015-10-17 10:45:08

非常好,谢谢分享。