MFC六大关键技术之仿真学习笔记(五)

来源:互联网 发布:c语言经典程序100例 编辑:程序博客网 时间:2024/05/01 04:36

            前面所有的基础,你可以说你觉得云里雾里的,所谓的"类别型录"网到底可以干什么,我们为什么需要花费这么多功夫去构建呢,在这一节我会慢慢道来。

我们希望在程序运行过程中动态生成某种"类别型录"中的对象,如 CWnd 我们可能会有这样的思路:

CObject *pClass = CRuntimeClass::CreateObject("CWnd"); 

或者 

CRuntimeClass *pRtclass = CRuntimeClass::Load("CWnd"); 

CObject *pClass = pRtclass -> CreateObject();

确实,如你所想,MFC也为你完成了类似这样的一套工作,这就是动态创建。


*DYNAMIC CREATION(动态创建)

首先我们对CRuntimeClass进行修改:

struct CRuntimeClass{//AttributesLPCSTR 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;}
测试结果:





0 0