MFC六大关键技术之仿真学习笔记(五)
2015-06-06 20:37
691 查看
前面所有的基础,你可以说你觉得云里雾里的,所谓的"类别型录"网到底可以干什么,我们为什么需要花费这么多功夫去构建呢,在这一节我会慢慢道来。
我们希望在程序运行过程中动态生成某种"类别型录"中的对象,如 CWnd 我们可能会有这样的思路:
CObject *pClass = CRuntimeClass::CreateObject("CWnd");
或者
CRuntimeClass *pRtclass = CRuntimeClass::Load("CWnd");
CObject *pClass = pRtclass -> CreateObject();
确实,如你所想,MFC也为你完成了类似这样的一套工作,这就是动态创建。
*DYNAMIC CREATION(动态创建)
首先我们对CRuntimeClass进行修改:
我们来看看CObject* CreateObject() 的实现:
再看看static CRuntimeClass* PASCAL Load()的实现:
其次,在动态创建时MFC加入了两个新的宏:
CRuntimeClass::CreateObject();
动态创建CFrameWnd如下图:
当然在运用时我们只需要在声明中加入DECLARE_DYNCREATE(class_name),cpp文件中加入IMPLEMENT_DYNCREATE(class_name,base_class_name) 即可完成以上复杂的过程。
当"类别型录"网中m_pfnCreateObject不为NUL的,都可以执行动态创建。
此处我们在main函数中测试一下仿真:
我们希望在程序运行过程中动态生成某种"类别型录"中的对象,如 CWnd 我们可能会有这样的思路:
CObject *pClass = CRuntimeClass::CreateObject("CWnd");
或者
CRuntimeClass *pRtclass = CRuntimeClass::Load("CWnd");
CObject *pClass = pRtclass -> CreateObject();
确实,如你所想,MFC也为你完成了类似这样的一套工作,这就是动态创建。
*DYNAMIC CREATION(动态创建)
首先我们对CRuntimeClass进行修改:
struct CRuntimeClass { //Attributes LPCSTR m_lpszClassName; int m_nObjectSize; UINT m_wSchema; CObject *(PASCAL *m_pfnCreateObject)(); CRuntimeClass *m_pBaseClass; CObject* CreateObject(); static CRuntimeClass* PASCAL Load(); static CRuntimeClass* pFirstClass; CRuntimeClass* m_pNextClass; };我们看到增加了两个成员函数:
CObject* CreateObject(); static CRuntimeClass* PASCAL Load();当然,在C++的struct中允许增加成员函数,而在C语言中我们只能够运用函数指针实现成员函数。
我们来看看CObject* CreateObject() 的实现:
CObject* CRuntimeClass::CreateObject() { if (m_pfnCreateObject == NULL) { TRACE1("error:Trying to create object which is not DECLARE_DYNCREATE OR DECLEARE_SERIAL: %hs.\n", m_lpszClassName); return NULL; } CObject* pObject = NULL; pObject = (*m_pfnCreateObject)(); return pObject; }即:CObject* CreateObject() 会在调用CRuntimeClass的m_pfnCreateObject指向的函数(若不为NULL)
再看看static CRuntimeClass* PASCAL Load()的实现:
CRuntimeClass* PASCAL CRuntimeClass::Load() { char szClassName[64]; CRuntimeClass* pClass; std::cout << "enter a class name...\n"; std::cin >> szClassName; for (pClass = pFirstClass; pClass != NULL;pClass=pClass->m_pNextClass) { if (strcmp(szClassName,pClass->m_lpszClassName) == 0) { return pClass; } } TRACE1("error: Class Not Found: %s\n", szClassName); return NULL; }即:Load()函数完成对"类别型录"进行遍历,返回符合的CRuntimeClass指针,从而进行我们下一步的动态创建。
其次,在动态创建时MFC加入了两个新的宏:
#define DECLARE_DYNCREATE(class_name) \ DECLARE_DYNAMIC(class_name) \ static CObject* PASCAL CreateObject(); #define IMPLEMENT_DYNCREATE(class_name,base_class_name) \ CObject* PASCAL class_name::CreateObject() \ { return new class_name ;} \ _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,class_name::CreateObject)其实DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 增加实现了
static CObject* PASCAL CreateObject(); CObject* PASCAL class_name::CreateObject() { return new class_name ;}即:在类中添加唯一一个静态成员函数,创建返回一个自身产生的对象。
_IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,class_name::CreateObject)即:类中的CRuntimeClass对象的m_pfnCreateObject 被指向 类的静态成员函数:CreateObject() ;(如 : CWnd::CreateObject ),并非CRuntimeClass中的 CObject*
CRuntimeClass::CreateObject();
动态创建CFrameWnd如下图:
当然在运用时我们只需要在声明中加入DECLARE_DYNCREATE(class_name),cpp文件中加入IMPLEMENT_DYNCREATE(class_name,base_class_name) 即可完成以上复杂的过程。
当"类别型录"网中m_pfnCreateObject不为NUL的,都可以执行动态创建。
此处我们在main函数中测试一下仿真:
int _tmain(int argc, _TCHAR* argv[]) { CWinApp *pApp = AfxGetApp(); pApp->InitApplication(); pApp->InitInstance(); pApp->Run(); CRuntimeClass* pClassRef; CObject* pOb; while (true) { if ((pClassRef = CRuntimeClass::Load()) == NULL) { break; } pOb = pClassRef->CreateObject(); if (pOb != NULL) { pOb->SayHello(); } } system("pause"); return 0; }测试结果:
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++中拷贝构造函数的应用详解
- C++中引用(&)的用法与应用实例分析
- C++使用CriticalSection实现线程同步实例
- Visual C++中MFC消息的分类
- C++智能指针实例详解