MFC 六大机制 (2) RTTI(运行时类型识别)
mfc,C++,RTTI,运行时类型识别,六大机制2016-06-20
struct CRuntimeClass
{
LPCSTR m_lpszClassName;
int m_ObjectSize;
UINT m_wSchema;
CObject* (PASCAL* m_pfnCreateObject)();
CRuntimeClass* m_pBaseClass;
CRuntimeClass* m_pNextClass;
const AFX_CLASSINIT* m_pClassInit;
};struct AFX_CLASSINIT
{ AFX_CLASSINIT(CRuntimeClass* pNewClass) { AfxClassInit(pNewClass); } };
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass);
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
pModuleState->m_classList.AddHead(pNewClass);
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
}#define DECLARE_DYNAMIC(class_name) \ public: \ static const CRuntimeClass class##class_name; \ virtual CRuntimeClass* GetRuntimeClass() const;
public: static const CRuntimeClass classCObject; virtual CRuntimeClass* GetRuntimeClass() const;
#define IMPLEMENT_DYNAMIC(class_name,base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL,NULL)
#define IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew,class_init) \
const CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
RUNTIME_CLASS(base_class_name), NULL, class_init }; \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS(class_name); }
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
const CRuntimeClass classCCmdTarget = {
CCmdTarget,sizeof(class CCmdTarget),0xFFFF,NULL,
((CRuntimeClass*)(&CObject::classCObject)),NULL,NULL };
CRuntimeClass* CCmdTarget::GetRuntimeClass() const
{ return ((CRuntimeClass*)(&CCmdTarget::classCCmdTarget)); }BOOL CObject::IsKindOf(const CRuntimeClass* pClass)const
{
CRuntimeClass* pClassThis = GetRuntimeClass();
while(pClassThis != NULL)
{
if(pClassThis == pClass)
{
cout<<GetRuntimeClass()->m_lpszClassName<<" is "<<pClass->m_lpszClassName<<endl;
return TRUE;
}
pClassThis = pClassThis->m_pBaseClass;
}
cout<<GetRuntimeClass()->m_lpszClassName<<" is not "<<pClass->m_lpszClassName<<endl;
return FALSE;
}//afx.h
class CObject;
struct CRuntimeClass;
struct AFX_CLASSINIT;
//演示需要,MFC实际上不包含<iostream>
#include <iostream>
using namespace std;
//实际上下面这些重定义写其他头文件中,MFC编程时通常会自动包含该头文件,为演示方便就写这了
#define FALSE 0;
#define TRUE 1;
#define PASCAL __stdcall
#define AFXAPI __stdcall
typedef char CHAR;
typedef const CHAR* LPCSTR;
typedef int BOOL;
typedef unsigned int UINT;
#define DECLARE_DYNAMIC(class_name) \
public: \
static const CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const;
#define IMPLEMENT_DYNAMIC(class_name,base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL,NULL)
#define IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew,class_init) \
const CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
RUNTIME_CLASS(base_class_name), NULL, class_init }; \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS(class_name); }
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
//CObect类声明
class CObject
{
public:
CObject();
virtual CRuntimeClass* GetRuntimeClass() const;
BOOL IsKindOf(const CRuntimeClass* pClass)const;
static CRuntimeClass classCObject;
};
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass);
/*
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
pModuleState->m_classList.AddHead(pNewClass);
AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
}
*/
struct AFX_CLASSINIT
{ AFX_CLASSINIT(CRuntimeClass* pNewClass) { AfxClassInit(pNewClass); } };
struct CRuntimeClass
{
LPCSTR m_lpszClassName;
int m_ObjectSize;
UINT m_wSchema; //分类编号(对不可分类的类,该值为-1)
CObject* (PASCAL* m_pfnCreateObject)();
CRuntimeClass* m_pBaseClass;
CRuntimeClass* m_pNextClass;
const AFX_CLASSINIT* m_pClassInit;
};
//afx.cpp
#include "afx.h"
//CObject类声明
CObject::CObject()
{
cout<<"CObject Constructor."<<endl;
}
BOOL CObject::IsKindOf(const CRuntimeClass* pClass)const
{
CRuntimeClass* pClassThis = GetRuntimeClass();
while(pClassThis != NULL)
{
if(pClassThis == pClass)
{
cout<<GetRuntimeClass()->m_lpszClassName<<" is "<<pClass->m_lpszClassName<<endl;
return TRUE;
}
pClassThis = pClassThis->m_pBaseClass;
}
cout<<GetRuntimeClass()->m_lpszClassName<<" is not "<<pClass->m_lpszClassName<<endl;
return FALSE;
}
CRuntimeClass* CObject::GetRuntimeClass() const
{
return &CObject::classCObject;
}
struct CRuntimeClass CObject::classCObject={
"COBject",sizeof(CObject),0xFFFF,NULL,NULL,NULL,NULL};
void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
{
//类别型录网的建立与维护,如完成 m_pNextClass 指针的赋值等。
}//afxwin.h
#pragma once
#include "afx.h"
//CCmdTarget类声明
class CCmdTarget : public CObject
{
DECLARE_DYNAMIC(CCmdTarget) //其实在 MFC 中是 DECLARE_DYNCREATE(),见下一章
public:
CCmdTarget();
};
//CDocument类声明
class CDocument : public CCmdTarget
{
DECLARE_DYNAMIC(CDocument) //其实在 MFC 中是 DECLARE_DYNCREATE(),见下一章
public:
CDocument();
};
//CWnd类声明
class CWnd : public CCmdTarget
{
DECLARE_DYNAMIC(CWnd) //其实在 MFC 中是 DECLARE_DYNCREATE(),见下一章
public:
CWnd();
virtual BOOL Create();
BOOL CreateEx();
virtual BOOL PreCreateWindow();
};
//CFrameWnd类声明
class CFrameWnd : public CWnd
{
DECLARE_DYNAMIC(CFrameWnd) //其实在 MFC 中是 DECLARE_DYNCREATE(),见下一章
public:
CFrameWnd();
};
//CView类声明
class CView : public CWnd
{
DECLARE_DYNAMIC(CView) //其实在 MFC 中是 DECLARE_DYNCREATE(),见下一章
public:
CView();
};
//CWinThread类声明
class CWinThread : public CCmdTarget
{
DECLARE_DYNAMIC(CWinThread) //其实在 MFC 中是 DECLARE_DYNCREATE(),见下一章
public:
CWnd* m_pMainWnd;
CWinThread();
virtual BOOL InitInstance();
virtual int Run();
};
//CWinApp类声明
class CWinApp : public CWinThread
{
DECLARE_DYNAMIC(CWinApp) //其实在 MFC 中是 DECLARE_DYNCREATE(),见下一章
public:
CWinApp();
virtual BOOL InitApplication();
virtual BOOL InitInstance(); //覆盖
virtual int Run(); //覆盖
};
//afxwin.cpp
#include "afxwin.h"
//这里导入"CMyApp.h"是为了使用 theApp 全局变量以使用改造版的 AfxGetApp()
#include "My.h"
extern CMyApp theApp;
//CCmdTarget类方法定义
IMPLEMENT_DYNAMIC(CCmdTarget,CObject)
CCmdTarget::CCmdTarget()
{
cout<<"CCmdTarget Constructor."<<endl;
}
//CDocument类方法定义
IMPLEMENT_DYNAMIC(CDocument,CCmdTarget)
CDocument::CDocument()
{
cout<<"CDocument Constructor."<<endl;
}
//CWnd类方法定义
IMPLEMENT_DYNAMIC(CWnd,CCmdTarget)
CWnd::CWnd()
{
cout<<"CWnd Constructor."<<endl;
}
BOOL CWnd::Create()
{
cout<<"CWnd::Create()."<<endl;
return TRUE;
}
BOOL CWnd::CreateEx()
{
cout<<"CWnd::CreateEx()."<<endl;
return TRUE;
}
BOOL CWnd::PreCreateWindow()
{
cout<<"CWnd::PreCreateWindow()."<<endl;
return TRUE;
}
//CFrameWnd类方法定义
IMPLEMENT_DYNAMIC(CFrameWnd,CWnd)
CFrameWnd::CFrameWnd()
{
cout<<"CFrameWnd Constructor."<<endl;
}
//CView类方法定义
IMPLEMENT_DYNAMIC(CView,CWnd)
CView::CView()
{
cout<<"CView Constructor."<<endl;
}
//CWinThread类方法定义
IMPLEMENT_DYNAMIC(CWinThread,CCmdTarget)
CWinThread::CWinThread()
{
cout<<"CWinThread Constructor."<<endl;
}
BOOL CWinThread::InitInstance()
{
cout<<"CWinThread::InitInstance()."<<endl;
return TRUE;
}
int CWinThread::Run()
{
cout<<"CWinThread::Run()."<<endl;
return 1;
}
//CWinApp类方法定义
IMPLEMENT_DYNAMIC(CWinApp,CWinThread)
CWinApp::CWinApp()
{
cout<<"CWinApp Constructor."<<endl;
}
BOOL CWinApp::InitInstance()
{
cout<<"CWinApp::InitInstance()."<<endl;
return TRUE;
}
BOOL CWinApp::InitApplication()
{
cout<<"CWinApp::InitApplication()."<<endl;
return TRUE;
}
int CWinApp::Run()
{
cout<<"CWinApp::Run()."<<endl;
return 1;
}
//My.cpp
#include "stdafx.h"
#include "My.h"
#include "MyFrame.h"
#include "MyDoc.h"
#include "MyView.h"
//CMyWinApp类方法定义
CMyApp::CMyApp()
{
cout<<"CMyApp Constructor."<<endl;
}
BOOL CMyApp::InitInstance() //覆盖
{
cout<<"CMyApp::InitInstance()."<<endl;
//下面的注释为 MFC 源码中的内容,使用RTTI实例化了CMyDoc、
//CMyFrame、CMyView,并且使用 CDocTemplate 类来连接管理
/*
// 注册应用程序的文档模板。文档模板
// 将用作文档、框架窗口和视图之间的连接
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CMyFrame), // 主 SDI 框架窗口
RUNTIME_CLASS(CMyView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
*/
this->m_pMainWnd = new CMyFrame();
return TRUE;
}
//全局变量
CMyApp theApp;
int main()
{
theApp.InitApplication();
theApp.InitInstance();
theApp.Run();
//随意写了几个测试用例
CObject cobject;
CCmdTarget ccmdtarget;
CWinThread cwinthread;
CWnd cwnd;
CWinApp cwinapp;
CView cview;
CFrameWnd cframewnd;
CDocument cdocument;
cout<<endl;
cobject.IsKindOf(RUNTIME_CLASS(CCmdTarget));
ccmdtarget.IsKindOf(RUNTIME_CLASS(CObject));
cview.IsKindOf(RUNTIME_CLASS(CCmdTarget));
cwinapp.IsKindOf(RUNTIME_CLASS(CObject));
cwnd.IsKindOf(RUNTIME_CLASS(CWinThread));
return 0;
}