继续分析MFC的两个技术
动态识别和动态创建这两个动态类型识别机制主要是为了让类型可以判断是否一致,为动态创建打上良好的基础 动态类型识别三要素: 1、继承自 CObject类 2、类内的:DECLARE_DYNAMIC(theclass) 3、类外:IMPLEMENT_DYNAMIC(theclass, baseclass) 动态类型识别技术代码如下: - #include <afxwin.h>
- #include <iostream>
- using namespace std;
- class CHuman:public CObject
- {
- DECLARE_DYNAMIC(CHuman)
- };
- IMPLEMENT_DYNAMIC(CHuman, CObject)
- class CWoman: public CHuman
- {
- DECLARE_DYNAMIC(CWoman)
- };
- IMPLEMENT_DYNAMIC(CWoman, CHuman)
- int main()
- {
- CWoman girlfriend;
- if(girlfriend.IsKindOf(RUNTIME_CLASS(CWnd)))
- {
- AfxMessageBox("是 CWnd 一类");
- }
- else
- {
- AfxMessageBox("非 CWnd 一类");
- }
- if (girlfriend.IsKindOf(RUNTIME_CLASS(CObject)))
- {
- AfxMessageBox("是 CObject 一类");
- }
- else
- {
- AfxMessageBox("非 CObject 一类");
- }
- return 0;
- }
复制代码注意的是这里的动态类型识别,并非意义上的继承关系,而是一串链表关系 看宏展开代码: 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); } //以上展开的内容宏参数都替换完毕了 编译测试可以运行 下面开始分析代码的含义: 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,代表后面没有了!!!画图表示含义 如下: 看看动态类型识别的函数: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版本 有目录看清楚一点 |