5.MFC运行时动态创建
2015-06-10 16:43
381 查看
在看这篇博客时如果你对MFC的RTTI还不了解,建议看我的前一篇博客/article/10898036.html
相对于前一篇将的运行时识别类型信息,动态创建只是在原来基础上做了一些改动而已。
程序的运行结果: CFrameWnd, CView 使用的动态创建宏
增加了两个新成员
宏也又了一些改变
在类中使用时也改成使用 新的两个宏 DECLARE_DYNCREATE IMPLEMENT_DYNCREATE 分别写在头文件和实现文件中
MFC.cpp
MFC.cpp 文件中主要观察 CRuntimeClass 新增的两个函数 CreatObject, Load
相对于前一篇将的运行时识别类型信息,动态创建只是在原来基础上做了一些改动而已。
程序的运行结果: CFrameWnd, CView 使用的动态创建宏
struct CRuntimeClass { LPCSTR m_lpszClassName; //类的名字 int m_nObjectSize; //类的大小 UINT m_wSchema; //shema number of the loaded class CObject* (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 __stdcall
struct CRuntimeClass { LPCSTR m_lpszClassName; //类的名字 int m_nObjectSize; //类的大小 UINT m_wSchema; //shema number of the loaded class CObject* (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 Load CObject* 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"); }
相关文章推荐
- iOS皮肤框架JJSkin介绍
- 【MySql】Column count doesn't match value count at row 1 解决方法
- 黑马程序员——学习日记之--IO流学习总结
- Oracle shrink space
- POJ 1753
- 计算机视觉杂谈
- 黑马程序员--冒泡排序法
- linux centOS安装proftpd
- MySQL 日志文件 说明
- NSDate如何获取一个月后的日期
- Threads, Events and QObjects
- hadoop2.x error记录
- CentOS7.0硬盘安装(双系统win8.1+CentOS7)遇到的问题及解决办法
- 排序算法之(5)——归并排序(递归实现)
- sqlserver 自增ID插入指定数据
- LeetCode 57:Insert Interval
- VirtualBox共享文件夹等高级特性
- Android基础教程(六)之----多选项CheckBox的综合应用
- POJ 1731
- POJ 1734