MFC仿真之RTTI

最近看<<深入浅出MFC>>很带感,这是看书的一些笔记。

RTTI(运行时类型识别),就是在构建类的时候将类的信息记录下来,并将这些信息用链表连接起来形成一张类别型录网,RTTI可以实现IsKindOf, 动态创建等技术。

MFC.h

#define BOOL int
#define TRUE 1
#define FALSE 0
#define LPCSTR LPSTR
typedef char*  LPSTR;
#define UINT unsigned int
#define PASCAL  __stdcall
#define NULL 0


#include <iostream>

using std::cin;
using std::cout;
using std::endl;

class CObject;

//该结构用于记录类的信息,以建立型录,达到RTTI的能力
//该结构的对象会以链表方式连接起来。
//CRunTimeClass对象的命名方式为:class+类名,比如CWnd的CRunTimeClass对象是classCWnd
struct CRunTimeClass
{
	LPSTR m_lpszClassName;						//类名
	int m_nObjecSize;							//类大小
	UINT m_wSchema;
	CObject* (PASCAL* m_pfnCreateObject) ();	//动态创建类对象的方法
	CRunTimeClass *m_pBaseClass;				//该类的基类
	static CRunTimeClass *pFirstClass;			//全局对象,型录表的表头
	CRunTimeClass *m_pNextClass;				//在链表中的下一个类

	CObject* CreateObject();					//动态创建对象
	static CRunTimeClass* PASCAL Load();
};

//宏DECLARE_DYNAMIC的作用就是把CRuntimeClass对象塞到类之中。
#define DECLARE_DYNAMIC(class_name) \
public: \
	static CRunTimeClass class##class_name; \
	virtual CRunTimeClass* GetRunTimeClass() const; 

//宏DECLARE_DYNAMIC的作用就是在DECLARE_DYNAMIC上实现动态创建
#define DECLARE_DYNCREATE(class_name) \
	DECLARE_DYNAMIC(class_name) \
	static CObject* PASCAL CreateObject();

//宏IMPLEMENT_DYNAMIC的作用就是做各CRuntimeClass对象的连接工作,使它们形成一个链表
#define IMPLEMENT_DYNAMIC(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)

//生成类的CRunTimeClass对象名
#define RUNTIME_CLASS(class_name) \
	(&class_name::class##class_name)

struct AFX_CLASSINIT
{
	//该结构的构造函数的作用就是将一个个CRuntimeClass的对象链接起来
	AFX_CLASSINIT(CRunTimeClass *pNewClass);
};

#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; } \



class CObject
{
public:
	CObject()
	{
		cout << "CObject Constructor!" << endl;
	}

	~CObject()
	{
		cout << "CObject Destructor!" << endl;
	}

	// 根据RTTI查看本类是否是pClass或pClass的子类
	BOOL IsKindOf(const CRunTimeClass *pClass) const;

	//作为RTTI的表头CObject要作特殊的处理,可以看作是DECLARE_DYNAMIC宏的展开方式
public:
	static CRunTimeClass classCObject;
	virtual CRunTimeClass* GetRunTimeClass() const;
};

//与消息有关的类
class CCmdTarget : public CObject
{
	DECLARE_DYNAMIC(CCmdTarget);

public:
	CCmdTarget() { cout << "CCmdTarget Constructor!" << endl; }
	~CCmdTarget() { cout << "CCmdTarget Destructor!" << endl; }

};

class CWinThread : public CCmdTarget
{
	DECLARE_DYNAMIC(CWinThread);

public:
	CWinThread() { cout << "CWinThread Constructor!" << endl; }
	~CWinThread() { cout << "CWinThread Destructor!" << endl; }

	virtual BOOL InitInstance() { 
		cout << "CWinThread::InitInstance()" << endl;
		return TRUE;
	}

	virtual int Run() {
		cout << "CWinThread::Run()" << endl;
		return 1;
	}
};

class CWnd;

class CWinApp : public CWinThread
{
	DECLARE_DYNAMIC(CWinApp);

public:
	CWinApp *m_pCurrentApp;		//应用程序实例
	CWnd *m_pMainWnd;		//程序主框架
public:
	CWinApp() { 
		m_pCurrentApp = this;
		cout << "CWinApp Constructor!" << endl; 
	}
	~CWinApp() { cout << "CWinApp Destructor!" << endl; }

	virtual BOOL InitApplication() {
		cout << "CWinApp::InitApplication()" << endl;
		return TRUE;
	}
	virtual BOOL InitInstance() { 
		cout << "CWinApp::InitInstance()" << endl;
		return TRUE;
	}
	virtual int Run() {
		cout << "CWinApp::Run()" << endl;
		return CWinThread::Run();
	}
};

class CWnd : public CCmdTarget
{
	DECLARE_DYNCREATE(CWnd);

public:
	CWnd() { cout << "CWnd Constructor!" << endl; }
	~CWnd() { cout << "CWnd Destructor!" << endl; }

	virtual BOOL Create();
	BOOL CreateEX();
	virtual BOOL PreCreateWindow();
};

class CFrameWnd : public CWnd
{
	DECLARE_DYNCREATE(CFrameWnd);

public:
	CFrameWnd() { cout << "CFrameWnd Constructor!" << endl; }
	~CFrameWnd() { cout << "CFrameWnd Destructor!" << endl; }

	virtual BOOL Create();
	virtual BOOL PreCreateWindow();
};

class CView : public CWnd
{
	DECLARE_DYNAMIC(CView);

public:
	CView() { cout << "CView Constructor!" << endl; }
	~CView() { cout << "CView Destructor!" << endl; }
};

class CDoucument : public CCmdTarget
{
	DECLARE_DYNAMIC(CDoucument);

public:
	CDoucument() { cout << "CDoucument Constructor!" << endl; }
	~CDoucument() { cout << "CDoucument Destructor!" << endl; }
};

// global function
CWinApp * AfxGetApp();

MY.h

#include <iostream>
#include "MFC.h"

class CMyWinApp : public CWinApp
{
//	DECLARE_DYNCREATE(CMyWinApp);

public:
	CMyWinApp() { cout << "CMyWinApp Constructor!" << endl; }
	~CMyWinApp() { cout << "CMyWinApp Destructor!" << endl; }

	virtual BOOL InitInstance();
};

class CMyFrame : public CFrameWnd
{
	DECLARE_DYNCREATE(CMyFrame);

public:
	CMyFrame();
	~CMyFrame() { cout << "CMyFrame Destructor!" << endl; }
};

class CMyView : public CView
{
	DECLARE_DYNCREATE(CMyView);

public:
	CMyView() { cout << "CMyView Constructor!" << endl; }
	~CMyView() { cout << "CMyView Destructor!" << endl; }
};

class CMyDoc : public CDoucument
{
	DECLARE_DYNCREATE(CMyDoc);

public:
	CMyDoc() { cout << "CMyDoc Constructor!" << endl; }
	~CMyDoc() { cout << "CMyDoc Destructor!" << endl; }
};

MFC.cpp

#include "MY.h"

CRunTimeClass * CRunTimeClass::pFirstClass = NULL;	

AFX_CLASSINIT::AFX_CLASSINIT(CRunTimeClass* pNewClass)
{
	pNewClass->m_pNextClass = CRunTimeClass::pFirstClass;
	CRunTimeClass::pFirstClass = pNewClass;
}

//根据CRunTimeClass对象动态创建对象
CObject* CRunTimeClass::CreateObject()
{
	if (m_pfnCreateObject == NULL)
	{
		cout << "Error:Trying to create object which is not DECLARE_DYNCREATE:" 
			<< m_lpszClassName << endl;
		return NULL;
	}

	CObject *object = NULL;
	object = (*m_pfnCreateObject)();
	return object;
}

//输入类名,若RTTI中存在则返回该类的CRunTimeClass对象
CRunTimeClass* PASCAL CRunTimeClass::Load()
{
	char szClassName[64];
	CRunTimeClass *pClass;
	
	cout << "enter a class name: ";
	cin >> szClassName;
	for (pClass = pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass)
	{
		if (strcmp(szClassName, pClass->m_lpszClassName) == 0)
			return pClass;
	}

	cout << "Error:Class not found: " << szClassName;
	return NULL;
}


//处理RTTI表的表头,可以看作是宏IMPLEMENT_DYNAMIC的展开方式
static char _lpszCOjbect[] = "CObject";
struct CRunTimeClass CObject::classCObject = {_lpszCOjbect, sizeof(CObject), 0xFFFF, NULL, NULL, NULL};
static AFX_CLASSINIT _initCObject(&CObject::classCObject);
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;
}


extern CMyWinApp theApp;

CWinApp* AfxGetApp()
{
	return theApp.m_pCurrentApp;
}

BOOL CWnd::Create()
{
	cout << "CWnd::Create()" << endl;
	return TRUE;
}

BOOL CWnd::CreateEX()
{
	cout << "CWnd::CreateEX()" << endl;
	PreCreateWindow();
	return TRUE;
}

BOOL CWnd::PreCreateWindow()
{
	cout << "CWnd::PreCreateWindow()" << endl;
	return TRUE;
}

BOOL CFrameWnd::Create()
{
	cout << "CFrameWnd::Create()" << endl;
	CreateEX();
	return TRUE;
}

BOOL CFrameWnd::PreCreateWindow()
{
	cout << "CFrameWnd::PreCreateWindow()" << endl;
	return TRUE;
}

IMPLEMENT_DYNAMIC(CCmdTarget, CObject);
IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget);
IMPLEMENT_DYNAMIC(CWinApp, CWinThread);
//IMPLEMENT_DYNAMIC(CMyWinApp, CWinApp);
IMPLEMENT_DYNCREATE(CWnd, CCmdTarget);
IMPLEMENT_DYNAMIC(CView, CWnd);
IMPLEMENT_DYNCREATE(CFrameWnd, CWnd);
IMPLEMENT_DYNAMIC(CDoucument, CCmdTarget);

MY.cpp

#include "MY.h"

// global objec
CMyWinApp theApp;

BOOL CMyWinApp::InitInstance()
{
	m_pMainWnd = new CMyFrame;
	return TRUE;
}

CMyFrame::CMyFrame()
{ 
	cout << "CMyFrame Constructor!" << endl; 
	Create();
}


IMPLEMENT_DYNCREATE(CMyFrame, CFrameWnd);
IMPLEMENT_DYNCREATE(CMyDoc, CDoucument);
IMPLEMENT_DYNCREATE(CMyView, CView);

//打印TRRI链表
void PrinAllClass()
{
	CRunTimeClass *pClass;
	for (pClass = CRunTimeClass::pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass)
	{
		cout << pClass->m_lpszClassName << " " << pClass->m_nObjecSize << endl;
	}
}

void main()
{
	//仿真MFC的运行
	CWinApp *pApp = AfxGetApp();
	pApp->InitApplication();
	pApp->InitInstance();
	pApp->Run();

	/**************************以下属于自定义**************************************/
	//TRRI的使用
	if (pApp->m_pMainWnd->IsKindOf(RUNTIME_CLASS(CWnd)))
		cout << "true" << endl;
	PrinAllClass();

	//动态创建对象,输入类名,若存在则会动态创建对象
	CRunTimeClass *pClass = NULL;
	CObject *pObject = NULL;
	while(1)
	{
		if ((pClass = CRunTimeClass::Load()) == NULL)
		{
			break;
		}
		pObject = pClass->CreateObject();
		if (pObject)
			cout << pClass->m_lpszClassName << " create Success!" << endl;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值