今天看了RTTI 的实现.理解了实现.
头文件里的DECLARE_DYNAMIC(C***)
实现文件里的IMPLEMENT_DYNAMIC(C***,CBase***)
这两个宏和
STRUCT AFX_CLASSINIT的构造函数用的实现好巧妙.
利用他们构造了一个链表.
- //mfc.h
- #ifndef _MFC_H
- #define _MFC_H
- #define BOOL int
- #define TRUE 1
- #define FALSE 0
- #define LPCTSTR LPSTR
- typedef char * LPSTR;
- #define UINT int
- #define PASCAL _stdcall
- #include <iostream>
- using namespace std;
- class CObject;
- struct CRuntimeClass
- {
- //Attributes
- LPCTSTR m_lpszClassName;
- int m_nObjectSize;
- UINT m_wSchema;//schema number of the loaded class
- CObject* (PASCAL* m_pfnCreateObject)();//NULL=>abstract class
- CRuntimeClass *pBaseClass;
- //CRuntimeClass objects linked together in simple list
- static CRuntimeClass* pFirstClass;// start of class list
- CRuntimeClass * m_pNextClass;//linkedlist of registered calsses
- };
- struct AFX_CLASSINIT
- {
- //constructor
- 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;
- #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)
- class CObject
- {
- public:
- CObject()
- {
- }
- ~CObject()
- {
- }
- virtual CRuntimeClass * GetRuntimeClass() const ;
- public:
- static CRuntimeClass classCObject;
- };
- class CCmdTarget : public CObject
- {
- DECLARE_DYNAMIC(CCmdTarget)
- public:
- CCmdTarget()
- {
- }
- ~CCmdTarget()
- {
- }
- };
- /
- class CWinThread: public CCmdTarget
- {
- DECLARE_DYNAMIC(CWinThread)
- public:
- CWinThread()
- {
- }
- ~CWinThread()
- {
- }
- virtual BOOL InitInstance()
- {
- return TRUE;
- }
- virtual int Run()
- {
- return 1;
- }
- };
- ///
- class CWnd;
- class CWinApp: public CWinThread
- {
- DECLARE_DYNAMIC(CWinApp)
- public:
- CWinApp* m_pCurrentWinApp;
- CWnd* m_pMainWnd;
- public:
- CWinApp()
- {
- m_pCurrentWinApp=this;
- }
- ~CWinApp()
- {
- }
- virtual BOOL InitApplication()
- {
- return TRUE;
- }
- virtual BOOL InitInstance()
- {
- return TRUE;
- }
- virtual int Run()
- {
- return CWinThread::Run();
- }
- };
- /
- class CDocument : public CCmdTarget
- {
- DECLARE_DYNAMIC(CDocument)
- public:
- CDocument()
- {
- }
- ~CDocument()
- {
- }
- };
- ///
- class CWnd : public CCmdTarget
- {
- DECLARE_DYNAMIC(CWnd)
- public:
- CWnd()
- {
- }
- ~CWnd()
- {
- }
- virtual BOOL Create();
- BOOL CreateEx();
- virtual BOOL PreCreateWindow();
- };
- class CFrameWnd : public CWnd
- {
- DECLARE_DYNAMIC(CFrameWnd)
- public:
- CFrameWnd()
- {
- }
- ~CFrameWnd()
- {
- }
- virtual BOOL Create();
- virtual BOOL PreCreateWindow();
- };
- /
- class CView : public CWnd
- {
- DECLARE_DYNAMIC(CView)
- public:
- CView()
- {
- }
- ~CView()
- {
- }
- };
- //global function
- CWinApp * AfxGetApp();
- #endif
- //my.h
- #ifndef _MY_H
- #define _MY_H
- #include <iostream>
- #include "MFC.H"
- using namespace std;
- class CMyWinApp : public CWinApp
- {
- public:
- CMyWinApp()
- {
- }
- ~CMyWinApp()
- {
- }
- virtual BOOL InitInstance();
- };
- class CMyFrameWnd : public CFrameWnd
- {
- public:
- CMyFrameWnd();
- ~CMyFrameWnd()
- {
- }
- };
- /
- class CMyDoc: public CDocument
- {
- public:
- CMyDoc()
- {
- }
- ~CMyDoc()
- {
- }
- };
- class CMyView: public CView
- {
- public:
- CMyView()
- {
- }
- ~CMyView()
- {
- }
- };
- void PrintAllClasses();
- #endif
- //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::pFirstClass=NULL;
- AFX_CLASSINIT::AFX_CLASSINIT( CRuntimeClass * pNewClass)
- {
- pNewClass->m_pNextClass=CRuntimeClass::pFirstClass;
- CRuntimeClass::pFirstClass=pNewClass;
- }
- CRuntimeClass * CObject::GetRuntimeClass() const
- {
- return & CObject::classCObject;
- }
- 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;
- }
- IMPLEMENT_DYNAMIC(CCmdTarget, CObject)
- IMPLEMENT_DYNAMIC(CWinThread,CCmdTarget)
- IMPLEMENT_DYNAMIC(CWinApp, CWinThread)
- IMPLEMENT_DYNAMIC(CWnd,CCmdTarget)
- IMPLEMENT_DYNAMIC(CFrameWnd,CWnd)
- IMPLEMENT_DYNAMIC(CDocument,CCmdTarget)
- IMPLEMENT_DYNAMIC(CView,CWnd)
- //global funciton
- CWinApp * AfxGetApp()
- {
- return theApp.m_pCurrentWinApp;
- }
- //my.cpp
- #include "my.h"
- CMyWinApp theApp;
- BOOL CMyWinApp::InitInstance()
- {
- m_pMainWnd=new CMyFrameWnd;
- return TRUE;
- }
- CMyFrameWnd::CMyFrameWnd()
- {
- Create();
- }
- void PrintAllClasses()
- {
- CRuntimeClass* pClass;
- //just walk through the simple list of registered classes
- for(pClass=CRuntimeClass::pFirstClass; pClass !=NULL; pClass=pClass->m_pNextClass)
- {
- cout<<pClass->m_lpszClassName<<endl;
- cout<<pClass->m_nObjectSize<<endl;
- cout<<pClass->m_wSchema<<endl;
- }
- }
- ///
- /
- ///
- void main()
- {
- CWinApp * pApp =AfxGetApp();
- pApp->InitApplication();
- pApp->InitInstance();
- pApp->Run();
- PrintAllClasses();
- }
为了加深印象,边理解边打了一变.终于理解了宏的缺点,一出现问题,很难找到错误.
我把 _lpsz##class_name,sizeof(class_name),wSchema,pfnNew, /
打成了 lpsz##class_name,sizeof(class_name),wSchema,pfnNew, /
就漏了一个_符号.出现了许多莫名的错误.
宏真是一把双刃剑啊.