VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 203|回复: 0

[分享] 浅谈MFC框架内部结构 四

[复制链接]
08_avatar_middle
最佳答案
10 
在线会员 发表于 2022-4-4 16:33:31 | 显示全部楼层 |阅读模式
继续分析MFC的两个技术
动态识别和动态创建这两个
动态类型识别机制主要是为了让类型可以判断是否一致,为动态创建打上良好的基础
动态类型识别三要素:
1、继承自 CObject类
2、类内的:DECLARE_DYNAMIC(theclass)
3、类外:IMPLEMENT_DYNAMIC(theclass, baseclass)
动态类型识别技术代码如下:
  1. #include <afxwin.h>
  2. #include <iostream>
  3. using namespace std;

  4. class CHuman:public        CObject
  5. {
  6.         DECLARE_DYNAMIC(CHuman)

  7. };
  8. IMPLEMENT_DYNAMIC(CHuman, CObject)

  9. class CWoman: public CHuman
  10. {
  11.         DECLARE_DYNAMIC(CWoman)
  12. };
  13. IMPLEMENT_DYNAMIC(CWoman, CHuman)

  14. int main()
  15. {
  16.         CWoman        girlfriend;
  17.         if(girlfriend.IsKindOf(RUNTIME_CLASS(CWnd)))
  18.         {
  19.                 AfxMessageBox("是 CWnd 一类");
  20.         }
  21.         else
  22.         {
  23.                 AfxMessageBox("非 CWnd 一类");
  24.         }

  25.         if (girlfriend.IsKindOf(RUNTIME_CLASS(CObject)))
  26.         {
  27.                 AfxMessageBox("是 CObject 一类");
  28.         }
  29.         else
  30.         {
  31.                 AfxMessageBox("非 CObject 一类");
  32.         }
  33.         return 0;
  34. }
复制代码
注意的是这里的动态类型识别,并非意义上的继承关系,而是一串链表关系 看宏展开代码:
1、DECLARE_DYNAMIC(CWoman)//展开代码:
public:
                static const CRuntimeClass classCWoman;
                virtual CRuntimeClass* GetRuntimeClass() const;

1、IMPLEMENT_DYNAMIC(CWoman, CHuman)//展开代码:
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL, NULL)//继续展开
AFX_COMDAT const CRuntimeClass CWoman::classCWoman =
{
                "CWoman",
                sizeof(class CWoman),
                0xFFFF,
                NULL,
                RUNTIME_CLASS(CHuman),
                NULL,
                NULL
};
CRuntimeClass* CWoman::GetRuntimeClass() const
{
                        return RUNTIME_CLASS(CWoman);
}
//以上展开的内容宏参数都替换完毕了 编译测试可以运行
浅谈MFC框架内部结构 四
下面开始分析代码的含义:
1、DECLARE_DYNAMIC(CWoman)
//该宏定义了 static const CRuntimeClass classCWoman;
//名字为 class关键字+类名!!!
//下面只关注类型不关注里面的函数,里面定义了不少函数 只关注赋值的类型
struct CRuntimeClass
{
        LPCSTR m_lpszClassName        ;        //类名称
        int m_nObjectSize;                //类大小
        UINT m_wSchema;                         //版本
        CObject* (PASCAL* m_pfnCreateObject)();         //动态创建使用到的
        CRuntimeClass* m_pBaseClass;                                //父类静态变量地址
        CRuntimeClass* m_pNextClass;                                
        const AFX_CLASSINIT* m_pClassInit;
};
//定义了一个虚函数:virtual CRuntimeClass* GetRuntimeClass() const;
1、IMPLEMENT_DYNAMIC(CWoman, CHuman)
1、classCWoman 该静态变量赋值
RUNTIME_CLASS(CHuman) == ((CRuntimeClass*)(&CHuman::classCHuman))
这里有个关键点 一定要分清楚 上面说的: 名字为 class关键字+类名!!!
子类是 class + 子类名字 / 父类是 class + 父类名字
所以父类的 静态变量 就是 classCHuman !!!
也就是说 RUNTIME_CLASS(CHuman) 完全是获取了 父类的静态变量地址!!!
2、GetRuntimeClass()该函数 构写代码:
RUNTIME_CLASS(CWoman)
这句代码的意思代表了 获取本类 classCWoman 变量地址!!!
到此 代码描述的很清楚了,也知道代码的含义了,又是一个链表。为啥?
因为 开头说了“动态类型识别三要素”也就意味着 从最下面的类获取 静态变量里面存放了父类的静态变量,依次推上去,到 [ 类名 + CObject == classCObject] 的时候 结构体的 CRuntimeClass* m_pBaseClass; NULL,代表后面没有了!!!画图表示含义 如下:
浅谈MFC框架内部结构 四
看看动态类型识别的函数:IsKindOf(const CRuntimeClass* pClass)
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
{
        CRuntimeClass* pClassThis = GetRuntimeClass();
//这里的this指针调用 GetRuntimeClass(); 也就是CWoman::girlfriend
//就是在获取本类的静态变量而已
        return pClassThis->IsDerivedFrom(pClass);
//这行代码本质就是在一个while循环里匹配是否与自己相等。
//因为子类变量有父类变量。
//反复让他 对比就可以了。其实很简单原理。
//可以自己跟入进去看看代码
}
到此为止 动态类型识别技术原理已经完全剖析开了。重要的一个 他是如何巧妙利用代码来进行编写的,一个重要的细节 就是 :“名字为 class关键字+类名!!!” 仔细体会下!

动态创建技术
动态类型创建机制是为了让模板类和视图类框架类有机结合一起的关键因素,SDI和MDI都是通过动态类型创建来实现的。
如果理解了 动态类型识别再来理解动态创建机制 就只是多了一个 “创建类的函数而已”!!
而这个函数,就只是简单的 return new class; 而已。很简单。代码:
#include <afxwin.h>
#include <iostream>
class CHuman: public CObject
{
        DECLARE_DYNCREATE(CHuman)
};
IMPLEMENT_DYNCREATE(CHuman, CObject)
class CWoman: public CHuman
{
        DECLARE_DYNCREATE(CWoman)
};
IMPLEMENT_DYNCREATE(CWoman, CHuman)
int main()
{
        CObject* pCob = RUNTIME_CLASS(CWoman)->CreateObject();
        if(pCob)
                AfxMessageBox("动态创建成功");
        else
                AfxMessageBox("失败");
        return 0;
}
动态创建技术三要素 如下:
1、必须继承自CObject
2、类内声明 DECLARE_DYNCREATE(class)
3、类外定义 IMPLEMENT_DYNCREATE(class, baseclass)
继续剖析代码 展开宏定义代码如下:
1、DECLARE_DYNCREATE(CWoman)
#define DECLARE_DYNCREATE(class_name) \
                DECLARE_DYNAMIC(class_name) \
        static CObject* PASCAL CreateObject();
就是动态类型识别技术 多了个静态函数  CreateObject();
而这个函数在CRuntimeClass也存在
2、IMPLEMENT_DYNCREATE(CWoman, CHuman)
CObject* PASCAL CWoman::CreateObject()
{
                return new CWoman;
}
IMPLEMENT_RUNTIMECLASS(CWoman, CHuman, 0xFFFF, CWoman::CreateObject, NULL)
动态类型识别技术宏不展开了 就一个函数 CreateObject() 简单的 return new CWoman;
IMPLEMENT_RUNTIMECLASS多了个参数 本类的 CWoman::CreateObject 是属于CRuntimeClass
CRuntimeClass 结构体的 CObject* (PASCAL* m_pfnCreateObject)();
Mian函数动态创建代码如下:
RUNTIME_CLASS(CWoman)->CreateObject();
RUNTIME_CLASS返回的就是 类的静态变量地址,在执行里面成员函数:
CObject* (PASCAL* m_pfnCreateObject)(); == 本类的CreateObject()
动态创建技术到此结束,MFC的六大技术还剩下最后的 序列化 也叫串行化,这个技术是用于磁盘文件读写也叫做数据永久化!!


可以下载WORD版本 有目录看清楚一点
浅谈MFC框架内部结构 四 MFC的原理及框架剖析.zip (639.49 KB, 下载次数: 10)

评分

参与人数 1威望 +15 驿站币 +15 热心值 +3 收起 理由
75_avatar_small wl1383838438 + 15 + 15 + 3 赞一个!

查看全部评分





上一篇:浅谈MFC框架内部结构 三
下一篇:浅谈MFC框架内部结构 五

本帖被以下淘专辑推荐:

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号-4 )|网站地图wx_jqr

GMT+8, 2022-7-7 19:05

Powered by CcTry.CoM

© 2009-2021 cctry.com

快速回复 返回顶部 返回列表