5.MFC运行时动态创建

在看这篇博客时如果你对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 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");
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值