MFC中的的RTTI和动态创建

MFC中的RTTI是通过建立一个类别型录网来实现。MFC中基本上所有的类都是派生自CObject这个类,通过在所有的类中添加一个公有的静态成员类,这个类通过链表链接组成一个类别识别的链表,这个链表的最终节点指向CObject,由于是静态成员,因此在编译中实际上成为了一个全局变量,在初始化中就实现了这个链表的构建,不必创建任何一个类就实现了链表的构建和连接。这个类为CRuntimeClass。

struct CRuntimeClass
{
	//Attributes
	LPCSTR m_lpszClassName;
	int m_nObjectSize;
	UINT m_wSchema;
	CObject* (PASCAL * m_pfnCreateObject)();
	CRuntimeClass * m_pBaseClass;

	CObject* CreateObject();
	static CRuntimeClass * PASCAL Load();
	//RuntimeClass link list
	static CRuntimeClass * m_pFirstClass;
	CRuntimeClass * m_pNextClass;

};
 

m_pFirstClass指向最后一个类,按照文件中类声明的顺序,及由基类到派生类的顺序,具体顺序如下。

以下是侯俊杰书中的MFC中RTTI和动态创建的仿真

//MFC.h
#define BOOL int
#define LPCSTR LPSTR
typedef char* LPSTR;
#define UINT int
#define PASCAL _stdcall
#define TRACE1 printf
#define TRUE 1
#define FALSE 0

#include <iostream>
#include <stdio.h>
#include<string.h>


class CObject;
struct CRuntimeClass
{
	//Attributes
	LPCSTR m_lpszClassName;
	int m_nObjectSize;
	UINT m_wSchema;
	CObject* (PASCAL * m_pfnCreateObject)();
	CRuntimeClass * m_pBaseClass;

	CObject* CreateObject();
	static CRuntimeClass * PASCAL Load();
	//RuntimeClass link list
	static CRuntimeClass * m_pFirstClass;
	CRuntimeClass * m_pNextClass;

};

struct AFX_CLASSINIT
{
	AFX_CLASSINIT(CRuntimeClass* pNewClass);
};

#define RUNTIME_CLASS(class_name) \
	(&class_name::class##class_name)

#define DECLEAR_DYNAMIC(class_name) \
	public: \
	static CRuntimeClass class##class_name; \
	virtual CRuntimeClass * GetRuntimeClass() const;

#define DECLARE_DYNCREATE(class_name) \
	DECLEAR_DYNAMIC(class_name) \
	static CObject * PASCAL CreateObject();

#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 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 * class_name::CreateObject() \
		{ return new class_name;} \
	_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, class_name::CreateObject) 

class CObject
{
public:
	CObject(){}
	~CObject(){}
	
	virtual CRuntimeClass * GetRuntimeClass() const;
	BOOL IsKindOf(const CRuntimeClass* pClass) const;

public:
	static CRuntimeClass  classCObject;
	virtual void SayHello()
	{
		std::cout<<"Hello CObject\n";
	}
};

class CCmdTarget : public CObject
{
	DECLEAR_DYNAMIC(CCmdTarget)
public:
	CCmdTarget(){}
	~CCmdTarget(){}
};

class CWinThread : public CCmdTarget
{
	DECLEAR_DYNAMIC(CWinThread)
public:
	CWinThread(){}
	~CWinThread(){}

	virtual BOOL InitInstance()
	{
		return TRUE;
	}
	virtual int Run()
	{
		return 1;
	}
};

class CWnd;

class CWinApp : public CWinThread
{
	DECLEAR_DYNAMIC(CWinApp)
public:
	CWinApp* m_pCurrentWinApp;
	CWnd* m_pMainWnd;

public:
	CWinApp(){}
	~CWinApp(){}

	virtual BOOL InitApplication()
	{
		return TRUE;
	}
	virtual BOOL InitInstance()
	{
		return TRUE;
	}

	virtual int Run()
	{
		return CWinThread::Run();
	}

};

class CDocument : public CCmdTarget
{
	DECLEAR_DYNAMIC(CDocument)
public:
	CDocument(){}
	~CDocument(){}
};

class CWnd : public CCmdTarget
{
	DECLARE_DYNCREATE(CWnd)
public:
	CWnd(){std::cout<<"CWnd Constructor \n";}
	~CWnd(){}
	virtual BOOL Create();
	BOOL CreateEx();
	virtual BOOL PreCreateWindow();
	void SayHello()
	{
		std::cout<<"Hello CWnd\n";
	}

};

class CFrameWnd : public CWnd
{
	DECLARE_DYNCREATE(CFrameWnd)
public:
	CFrameWnd()
	{
		std::cout<<"CFrameWnd Constrcutor\n";
	}
	~CFrameWnd(){}
	BOOL Create();
	virtual BOOL PreCreateWindow();
	void SayHello()
	{
		std::cout<<"Hello CFrameWnd\n";
	}
};

class CView : public CWnd
{
	DECLEAR_DYNAMIC(CView)
public:
	CView(){}
	~CView(){}
};

CWinApp *AfxGetApp();


//MFC.cpp
#include "MY.h"

extern CMyWinApp theApp;

static char szCObject[] = "CObject";
struct CRuntimeClass CObject::classCObject = { szCObject, sizeof(CObject), 0xffff, NULL, NULL, NULL};
static AFX_CLASSINIT _init_CObject(&CObject::classCObject);

CRuntimeClass* CRuntimeClass::m_pFirstClass = NULL;

AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pNewClass)
{
	pNewClass->m_pNextClass = CRuntimeClass::m_pFirstClass;
	CRuntimeClass::m_pFirstClass = pNewClass;
}

CObject * CRuntimeClass::CreateObject()
{
	if (m_pfnCreateObject == NULL)
	{
		TRACE1("Error: trying to create object which is not declare");
		return NULL;
	}
	CObject *pCObject = NULL;
	pCObject = (*m_pfnCreateObject)();
	return pCObject;
}

CRuntimeClass* PASCAL CRuntimeClass::Load()
{
	char szClassName[64];
	CRuntimeClass *pClass;

	std::cout<<"enter a class name:";
	std::cin>>szClassName;

	for (pClass = m_pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass)
	{
		if (strcmp(szClassName, pClass->m_lpszClassName) == 0)
		{
			return pClass;
		}
	}

	TRACE1("Error: Class not found\n");
	return NULL;
}

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

BOOL CWnd::Create()
{
	return TRUE;
}

BOOL CWnd::CreateEx()
{
	PreCreateWindow();
	return TRUE;
}

BOOL CWnd::PreCreateWindow()
{
	return TRUE;
}
BOOL CFrameWnd::Create()
{
	CreateEx();
	return TRUE;
}
BOOL CFrameWnd::PreCreateWindow()
{
	return TRUE;
}

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

IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
IMPLEMENT_DYNAMIC(CWinThread, CCmdTarget)
IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
IMPLEMENT_DYNAMIC(CDocument, CCmdTarget)
IMPLEMENT_DYNCREATE(CWnd, CCmdTarget)
IMPLEMENT_DYNAMIC(CView, CWnd)
IMPLEMENT_DYNCREATE(CFrameWnd, CWnd)

//MY.h
#include "MFC.h"

class CMyWinApp : public CWinApp
{
public:
	CMyWinApp(){}
	~CMyWinApp(){}

	virtual BOOL InitInstance();
};

class CMyFrameWnd : public CFrameWnd
{
	DECLARE_DYNCREATE(CMyFrameWnd)
public:
	CMyFrameWnd();
	~CMyFrameWnd(){}
	void SayHello()
	{
		std::cout<<"Hello CMyFrameWnd\n";
	}
};

class CMyDoc : public CDocument
{
	DECLARE_DYNCREATE(CMyDoc)
public:
	CMyDoc(){}
	~CMyDoc(){}
	void SayHello()
	{
		std::cout<<"Hello CMyDoc\n";
	}
};

class CMyView : public CView
{
	DECLARE_DYNCREATE(CMyView)
public:
	CMyView()
	{
		std::cout<<"CMyView Constructor\n";
	}
	~CMyView(){}

	void SayHello()
	{
		std::cout<<"Hello CMyView\n";
	}
};


void AfxPrintAllClasses();

//MY.cpp
#include "MY.h"

CMyWinApp theApp;

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

CMyFrameWnd::CMyFrameWnd()
{
	std::cout<<"CMyFrameWnd Constructor\n";
	Create();
}

IMPLEMENT_DYNCREATE(CMyFrameWnd, CFrameWnd)
IMPLEMENT_DYNCREATE(CMyDoc, CDocument)
IMPLEMENT_DYNCREATE(CMyView, CView)

//main.cpp
#include "MY.h"

int main(int argc, char argv[])
{
	CWinApp *pApp = AfxGetApp();
	pApp->InitApplication();
	pApp->InitInstance();
	pApp->Run();

	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值