5.MFC运行时动态创建

来源:互联网 发布:web编程工具 编辑:程序博客网 时间:2024/06/07 07:28

在看这篇博客时如果你对MFC的RTTI还不了解,建议看我的前一篇博客http://blog.csdn.net/lingdi2000/article/details/46441629

相对于前一篇将的运行时识别类型信息,动态创建只是在原来基础上做了一些改动而已。

程序的运行结果: CFrameWnd, CView 使用的动态创建宏

struct CRuntimeClass{LPCSTR m_lpszClassName; //类的名字int m_nObjectSize; //类的大小UINT m_wSchema; //shema number of the loaded classCObject* (PASCAL* m_pfnCreateObject)(); //NULL=> abstract class,一个指向非空的函数指针CRuntimeClass* m_pBaseClass;//表示 基类的 CRuntimeClass//调用 m_pfnCreateObject 来创建 对象CObject* CreateObjct();//通过类名获取对应的CRuntimeClas* static CRuntimeClass* PASCAL Load(const char* classname);static CRuntimeClass* pFirstClass;// 类链表的头指针CRuntimeClass* m_pNextClass;// 用来构建和访问类链表};
增加了两个新成员

//调用 m_pfnCreateObject 来创建 对象CObject* CreateObjct();//通过类名获取对应的CRuntimeClas* static CRuntimeClass* PASCAL Load(const char* classname);


宏也又了一些改变

#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 分别写在头文件和实现文件中
MFC.cpp
#pragma once#include<iostream>using namespace std;class CObject;#define BOOL int#define TRUE 1#define FLASE 0#define LPCSTR const char*#define LPSTR char*s#define UINT int#define PASCAL __stdcallstruct CRuntimeClass{LPCSTR m_lpszClassName; //类的名字int m_nObjectSize; //类的大小UINT m_wSchema; //shema number of the loaded classCObject* (PASCAL* m_pfnCreateObject)(); //NULL=> abstract class,一个指向非空的函数指针CRuntimeClass* m_pBaseClass;//表示 基类的 CRuntimeClass//调用 m_pfnCreateObject 来创建 对象CObject* CreateObjct();//通过类名获取对应的CRuntimeClas* static CRuntimeClass* PASCAL Load(const char* classname);static CRuntimeClass* pFirstClass;// 类链表的头指针CRuntimeClass* m_pNextClass;// 用来构建和访问类链表};struct AFX_CLASSINIT{AFX_CLASSINIT(CRuntimeClass* pNewClass);};//#define RUNTIME_CLASS(class_name)\(&class_name::class##class_name)//声明定义的宏#define DECLARE_DYNAMIC(class_name)\public:\static CRuntimeClass class##class_name; \virtual CRuntimeClass* GetRuntimeClass() const;//实现定义的宏, 宏中使用一个 # 表示 用引号括起后面的内容 "class_name", 两个引号表示连接#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew)\static char _lpsz##class_name[] = #class_name; \CRuntimeClass class_name::class##class_name = { \_lpsz##class_name, sizeof(class_name), wSchema, pfnNew, \RUNTIME_CLASS(base_class_name), NULL }; \static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name); \CRuntimeClass* class_name::GetRuntimeClass() const \{ return &class_name::class##class_name; } \#define DECLARE_DYNCREATE(class_name)\DECLARE_DYNAMIC(class_name)\static CObject* PASCAL CreateObject();//增加了创建对象的函数#define IMPLEMENT_DYNAMICLASS(class_name, base_class_name)\_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xffff, NULL)#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)class CObject{public:CObject::CObject(){}CObject::~CObject(){}virtual CRuntimeClass* GetRuntimeClass() const;BOOL IsKindOf(const CRuntimeClass* pClass) const;public:static CRuntimeClass classCObject;};class CCmdTarget :public CObject{DECLARE_DYNAMIC(CCmdTarget)/*#define DECLARE_DYNAMIC(CCmdTarget)\public:\static CRuntimeClass class##CCmdTarget; \virtual CRuntimeClass* GetRuntimeClass() const;*/public:CCmdTarget::CCmdTarget(){}CCmdTarget::~CCmdTarget(){}};class CWinThread : public CCmdTarget{DECLARE_DYNAMIC(CWinThread)public:virtual bool InitInstance(){cout << "CWinThread:InitInstance \n";return true;}virtual int Run(){cout << "CWinThread:Run \n";return 1;}};//先声音 CWnd类 因为在 CWinApp中需要用到,但是却没有 实际定义 CWnd这个类class CWnd;class CWinApp : public CWinThread{DECLARE_DYNAMIC(CWinApp)public:CWinApp* m_pCurrentWinApp;CWnd* m_pMainWnd;public:CWinApp::CWinApp(){m_pCurrentWinApp = this;}virtual bool InitInstance(){cout << "CWinApp:InitInstance \n";return true;}virtual int Run(){cout << "CWinApp:Run \n";return CWinThread::Run();}virtual bool InitApplication(){cout << "CWinApp:InitApplication \n";return true;}};class CDocument : public CCmdTarget{DECLARE_DYNAMIC(CDocument)public:CDocument::CDocument(){}CDocument::~CDocument(){}};class CWnd : public CCmdTarget{DECLARE_DYNAMIC(CWnd)public:virtual bool Create();bool CreateEx();virtual bool PreCreateWindow();};class CView : public CWnd{DECLARE_DYNCREATE(CView)public:CView::CView(){}CView::~CView(){}};class CFrameWnd : public CWnd{DECLARE_DYNCREATE(CFrameWnd)public:CFrameWnd::CFrameWnd(){}CFrameWnd::~CFrameWnd(){}bool Create();virtual bool PreCreateWindow();};CWinApp* AfxGetApp();


MFC.cpp 文件中主要观察 CRuntimeClass 新增的两个函数 CreatObject, Load
#include "MFC.h"static char lpszObject[] = "CObject";//作为链表的尾节点。CObject 有一些特殊,其没有基类struct CRuntimeClass CObject::classCObject = {lpszObject, sizeof(CObject), 0xffff, NULL, NULL, NULL};static AFX_CLASSINIT _initCObject(&CObject::classCObject);//静态类成员必须,在实现文件中定义才可以使用CRuntimeClass* CRuntimeClass::pFirstClass = NULL;//将节点连接起来AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pNewClass){pNewClass->m_pNextClass = CRuntimeClass::pFirstClass;CRuntimeClass::pFirstClass = pNewClass;}CRuntimeClass* CObject::GetRuntimeClass() const{//返回这个类的 运行时类return &CObject::classCObject;}BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const{CRuntimeClass* pClassThis = GetRuntimeClass();while (pClassThis != NULL){if (pClassThis == pClass)return TRUE;pClassThis = pClassThis->m_pBaseClass;}return false;}///////////////Create LoadCObject* CRuntimeClass::CreateObjct(){if (m_pfnCreateObject == NULL){printf("Error: Trying to Create object which is not DECLARE_DYNCREATE \n");return NULL;}CObject* pObject = NULL;pObject = (*m_pfnCreateObject)();return pObject;}CRuntimeClass*  CRuntimeClass::Load(const char* classname){CRuntimeClass *pClass = NULL;for (pClass = CRuntimeClass::pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass){if (strcmp(classname, pClass->m_lpszClassName) == 0){return pClass;}}cout << "Error: Class not found: " << classname << endl;return NULL;}IMPLEMENT_DYNAMICLASS(CCmdTarget, CObject)//可以看一下替换后的结果/*//我们暂时先不管0xffff, NULL 这两个参数#define IMPLEMENT_DYNAMICLASS(CCmdTarget, CObject)\_IMPLEMENT_RUNTIMECLASS(CCmdTarget, CObject, 0xffff, NULL)#define _IMPLEMENT_RUNTIMECLASS(CCmdTarget, CObject, wSchema, pfnNew)\static char _lpszCCmdTarget[] = "CCmdTarget"; \为类创建一个字符串名称CRuntimeClass CCmdTarget::classCCmdTarget = { \初始化类的静态成员变量,CRuntimeClass ,类的静态成员变量必须在使用前初始化_lpszCCmdTarget, sizeof(CCmdTarget), wSchema, pfnNew, \//这里对照结构体一一赋值RUNTIME_CLASS(CObject), NULL }; \static AFX_CLASSINIT _init_CCmdTarget(&class_name::classCCmdTarget); \ //先留着 这部分还没有用到CRuntimeClass* CCmdTarget::GetRuntimeClass() const \{ return &class_name::classCCmdTarget; } \*/IMPLEMENT_DYNAMICLASS(CWinThread, CCmdTarget)IMPLEMENT_DYNAMICLASS(CWinApp, CWinThread)IMPLEMENT_DYNAMICLASS(CWnd, CCmdTarget)IMPLEMENT_DYNCREATE(CFrameWnd, CWnd)IMPLEMENT_DYNAMICLASS(CDocument, CCmdTarget)IMPLEMENT_DYNCREATE(CView, CWnd)bool CWnd::Create(){return true;}bool CWnd::CreateEx(){//由于PreCrete是虚函数,所以PreCreateWindow属于那个类根据this指针决定PreCreateWindow();return true;}bool CWnd::PreCreateWindow(){return true;}bool CFrameWnd::Create(){//必然是基类的CraeteEx 因为CFrameWnd没有重写CreateEx();return true;}bool CFrameWnd::PreCreateWindow(){return true;}void PrintAllClasses(){CRuntimeClass* pClass;for (pClass = CRuntimeClass::pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass){cout << "ClassName: " << pClass->m_lpszClassName << endl;cout << "ClassSize: " << pClass->m_nObjectSize << endl;cout << "ClassSchema: " << pClass->m_wSchema << endl;cout << endl;}}void main(){PrintAllClasses();CRuntimeClass *pClassRef = NULL;CObject *pObj = NULL;char name[64] = { 0 };while (1){cin >> name;pClassRef = CRuntimeClass::Load(name);if (pClassRef == NULL)break;pObj = pClassRef->CreateObjct();if (pObj != NULL){cout << "create success \n";}}system("pause");}




0 0
原创粉丝点击