最近看<<深入浅出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;
}
}