RTTI(Runtime Type Identification£¬ÔËÐÐʱÀàÐÍʶ±ð) ³ÌÐòÄܹ»Ê¹ÓûùÀàµÄÖ¸Õë»òÒýÓÃÀ´¼ì²éÕâЩָÕë»òÒýÓÃËùÖ¸µÄ¶ÔÏóµÄʵ¼ÊÅÉÉúÀàÐÍ¡£MFC ÔçÔÚ±àÒëÆ÷Ö§³Ö RTTI ֮ǰ£¬¾Í¾ßÓÐÁËÕâÏîÄÜÁ¦¡£³Ð½ÓÉÏÒ»Õ£¬ÎÒÃÇÏÖÔÚÒªÔÚ Console ³ÌÐòÖн« RTTI ·ÂÕæ³öÀ´¡£ÎÒÏ£ÍûÎÒµÄÀà¿â¾ß±¸ IsKindOf() µÄÄÜÁ¦£¬Äܹ»ÔÚÖ´ÐÐÆ÷¼ì²éij¸ö¶ÔÏóÊÇ·ñ"ÊôÓÚijÖÖÀà"£¬²¢´«»Ø TRUE »ò FALSE¡£ÎªÁ˸üÖ±¹ÛµØ²é¿´½á¹û£¬ÎÒÔÚ IsKindOf() ÖмÓÈëÁËÊä³ö£¬Ê¹Æä´ïµ½ÈçϵÄЧ¹û:
RTTIÄÜ×öʲô£¿
//ËæÒâдÁ˼¸¸ö²âÊÔÓÃÀý
CObject cobject;
CCmdTarget ccmdtarget;
CWnd cwnd;
CWinApp cwinapp;
CView cview;
//RUNTIME_CLASS »áÔÚºóÎÄÖÐÏê½â
cobject.IsKindOf(RUNTIME_CLASS(CCmdTarget));
ccmdtarget.IsKindOf(RUNTIME_CLASS(CObject));
cwnd.IsKindOf(RUNTIME_CLASS(CWinThread));
cwinapp.IsKindOf(RUNTIME_CLASS(CObject));
cview.IsKindOf(RUNTIME_CLASS(CCmdTarget));
Ó¦¸ÃÓÐÈçÏÂÊä³ö:
COBject is not CCmdTarget
CCmdTarget is COBject
CView is CCmdTarget
CWinApp is COBject
CWnd is not CWinThread
ΪÁË´ïµ½ÉÏÊöÄ¿±ê£¬±¾ÎĽ«·ÖΪËĸö²¿·Ö½²½â:
1.CRunTimeClass Àà
2.Àà±ðÐÍÂ¼Íø
3.DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC ºê
4.IsKindOf(ÀàÐÍʶ±ð) ʵÏÖ
Ïà¶ÔÓÚÉÏÒ»Õ²©¿ÍÖеĴúÂ룬±¾ÕÂÖ»ÐÞ¸ÄÁË [afx.h] [afx.cpp] [afxwin.h] [afxwin.cpp] [My.cpp] 5¸öÎļþ£¬¶ÁÕß¿ÉÒÔÊÖ¶¯Ð޸ģ¬Ò²¿ÉÒÔ´ÓÎÄÕµײ¿¸½Â¼Ò»¸ø³öµÄÁ´½ÓÏÂÔØÍêÕûÔ´Âë¡£
1.CRunTimeClass Àà
ÈçºÎÉè¼Æ RTTI ÄØ£¿µ±ÄãÄÃ×ÅÒ»¸ö²úÆ·£¬ÏëÒªÖªµÀËüµÄÐͺţ¬ÊDz»ÊǾ͵ÃÈ¥²éËüµÄÐÍºÅ±í£¿Í¬ÑùµØ£¬Òª´ïµ½ RTTI µÄÄÜÁ¦£¬ÎÒÃDZØÐë¸øÃ¿Ò»¸öÀàÌùÉÏÒ»¸ö±êÇ©(×¢Òâ²»ÊǶÔÏó¶øÊÇÀà)£¬ÉÏÃæÐ´Ã÷Á˸ÃÀàÊÇʲô£¬ËüµÄ»ùÀàÊÇʲôµÈµÈ£¬¼´ÎÒÃÇ(Àà¿âµÄÉè¼ÆÕß) Ò»¶¨ÒªÔÚÀ๹½¨ÆðÀ´µÄʱºò£¬¼Ç¼±ØÒªµÄÐÅÏ¢£¬´æ·ÅÕâЩÐÅÏ¢µÄ½á¹¹³ÆÎªÐͼ£¬Ðͼ×îºÃÒÔÁ´±íÐÎʽÁ¬½Ó³ÉΪ"Àà±ðÐÍÂ¼Íø"£¬½«À´·½±ãÒ»Ò»±È½Ï¡£
ÎÒÃÇÕâ·Ý"Àà±ðÐÍÂ¼Íø"µÄÁ´±íÔªËØ£¬½«ÒÔ CRuntimeClass ÃèÊöÖ®£¬¸Ã½á¹¹ÈçÏÂËùʾ:
[cpp] view plain copy
ÔÚCODEÉϲ鿴´úÂëÆ¬ÅÉÉúµ½ÎҵĴúÂëÆ¬
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; };
|
LPCSTR m_lpszClassName:ÀàÃû³Æ
m_ObjectSize:¶ÔÏó´óС
m_Schema:·ÖÀà±àºÅ(¶Ô²»¿É·ÖÀàµÄÀ࣬¸ÃֵΪ-1,¼´ 0xFFFF)
(*m_pfnCreateObject)():ÊÇÒ»¸öÖ¸ÏòȱʡµÄ¹¹Ô캯ÊýµÄº¯ÊýÖ¸Õ룬¸Ã¹¹Ô캯Êý´´½¨Ò»¸öÄãµÄÀàµÄ¶ÔÏó£¨Ö»ÓÐÔÚÀàÖ§³Ö¶¯Ì¬´´½¨Ê±²ÅÓÐЧ£»·ñÔò£¬·µ»ØNULL£©¡£
m_pBaseClass:Ö¸Ïò»ùÀàµÄÖ¸Õë
m_pNextClass:Ö¸ÏòÏÂÒ»¸öÐͼ±íµÄÖ¸Õë
m_pClassInit:ÓÃÓÚÕû¸öÀà±ðÐÍÂ¼ÍøµÄ¹¹½¨Óëά»¤
ÆäÖÐ×îºóÒ»¸ö³ÉÔ±±äÁ¿Îª AFX_CLASSINIT ½á¹¹ÌåµÄÖ¸Õ룬¸Ã½á¹¹ÌåÈçÏ£¬ÀïÃæÖ»ÓÐÒ»¸ö¹¹Ô캯Êý(×¢ÒâÓëCµÄÇø±ð£¬C++ ½á¹¹Ìå¿ÉÒÔÓëÀàÏàËÆ)£¬¸Ãº¯ÊýµÄ pModuleState->m_classList.AddHead(pNewClass) ²Ù×÷¼´ÊÇÔÚ¹¹½¨Õâ¸öÀà±ðÐÍÂ¼Íø£¬µ«ÕâÀï·ÂÕæ²»ÐèÒª£¬¾Í²»ÉÁË£¬ÎÒÃÇÔÚ´úÂëÖн«¸Ã¹¹Ô캯ÊýдΪ¿Õº¯Êý¾ÍÐС£
[cpp] view plain copy
ÔÚCODEÉϲ鿴´úÂëÆ¬ÅÉÉúµ½ÎҵĴúÂëÆ¬
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); }
|
ÿһ¸öÓûʵÏÖ RTTI µÄÀà¶¼±ØÐëÓÐ CRuntimeClass ½á¹¹£¬Òò´Ëÿһ¸öÓûʵÏÖ RTTI µÄÀàÖУ¬¾Í±ØÐëÓÐÒ»¸ö static CRuntimeClass ±äÁ¿¡£¶ÔÓÚÀàÖÐµÄ CRuntimeClass ½á¹¹£¬ÎÒÃÇÓà "class"+ÀàÃû À´ÃüÃûÖ®£¬±ÈÈç CObject ÖÐµÄ CRuntimeClass ½á¹¹¾Í±»ÃüÃûΪ: classCObject¡£È»ºó£¬¾ÓÉijÖÖÊֶν«ËùÓÐ CRuntimeClass ½á¹¹×é³ÉÒ»ÕÅ"Àà±ðÐÍÂ¼Íø"¡£
2.Àà±ðÐÍÂ¼Íø
ËùÓÐ CRuntimeClass ×é³ÉµÄ"Àà±ðÐÍÂ¼Íø"Ó¦¸Ã³¤³ÉÕâÑù(ÒԸ÷ÂÕæÖÐÉæ¼°µÄÀàΪÀý):

ÆäÖУ¬Í·½áµãµÄ´´½¨¡¢Á´±íµÄά»¤Í¨Í¨½»¸øÁË m_pClassInit Ö¸ÏòµÄÀàµÄ¹¹Ôì·½·¨ÁË£¬ÉÔºó»á½éÉܵ½¡£
3.DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC ºê
RTTI µÄʵÏÖÆäʵ¾ÍÊÇ RuntimeClass ½á¹¹×é³ÉµÄÁ´±í¼ÓÉÏÒ»¶ÑºêʵÏֵģ¬ËùÒÔ½ÓÏÂÀ´½«»á½éÉÜÒ»¶Ñºê£¬¿´ÆðÀ´¿ÉÄÜÓеãÏÅÈË£¬²»ÒªÅ£¬²»¹ý¾ÍÊÇÎÄ×ÖÌæ»»°ÕÁË£¬¸ú×ÅÎÒÒ»²½Ò»²½¿´¾ÍÊÇÁË¡£
Ç°ÃæÒѾ˵Ã÷ÁË£¬Ã¿Ò»¸öÀàÖж¼±ØÐëÉùÃ÷Ò»¸ö static RuntimeClass ±äÁ¿ÓÃÓÚÀàÐÍʶ±ð£¬Í¬Ê±Ò²ÐèÒªÒ»¸ö³ÉÔ±º¯ÊýÄܹ»»ñµÃ¸ÃÀàµÄ RuntimeClass ½á¹¹µÄµØÖ·£¬ÓÚÊÇÒ»¸ö CRuntimeClass* GetRuntimeClass() º¯ÊýÊDZØÐèµÄ£¬ÓÉÓÚÿһ¸öÀà¶¼ÓУ¬ÓÚÊÇÎÒÃǽ«ÆäÉùÃ÷ΪÐ麯Êý virtual¡£¼ÈÈ»ÎÒÃÇÐèÒªÔÚÿһ¸öÀàÖÐÉùÃ÷ÕâЩÄÚÈÝ£¬È»ºóÔÚÿһ¸öʵÏÖÎļþÖÐ¶Ô RuntimeClass ½á¹¹Ìî³ä£¬²¢ÊµÏÖ GetRuntimeClass() º¯Êý£¬ÄÇΪʲô²»ÓúêÀ´¼ò»¯ÕâЩ²Ù×÷ÄØ£¿¼ÙÉèÎÒÃÇÄÜÓà DECLARE_DYNAMIC Íê³ÉÉùÃ÷£¬ÄÜÓà IMPLEMENT_DYNAMIC Íê³ÉʵÏÖ£¬Æñ²»ÃÀÔÕ£¿ÓÚÊǾͳöÏÖÁËÏÂÃæµÄÉùÃ÷ºê¶¨Òå DECLARE_DYNAMIC:
#define DECLARE_DYNAMIC(class_name) \
public: \ static const CRuntimeClass class##class_name; \ virtual CRuntimeClass* GetRuntimeClass() const;
|
·ûºÅ"\"±íʾ»»ÐÐÁ¬½Ó£¬ÎÒÃÇÒ²¿ÉÒÔÈ¥µôËùÓеÄ"\"²¢°Ñºêд³ÉÒ»ÐУ¬´úÂëÒ²Êǵȼ۵ġ£##±íʾ°Ñºê²ÎÊýÃûÓëºê¶¨Òå´úÂëÐòÁÐÖеıêʶ·ûÁ¬½ÓÔÚÒ»Æð£¬ÐγÉÒ»¸öеıêʶ·û¡£Èç¹ûÎÒÃÇÕâôµ÷ÓÃ:
DECLARE_DYNAMIC(CObject)
ºêÌæ»»ºóµÄ½á¹ûΪ:
public:
static const CRuntimeClass classCObject; virtual CRuntimeClass* GetRuntimeClass() const;
|
ÉùÃ÷ÍêÁË£¬½ÓÏÂÀ´±àдʵÏֵĺ궨Òå IMPLEMENT_DYNAMIC:
#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))
|
ÓÉÓÚ IMPLEMENT_RUNTIMECLASS ºêÔÚ"¶¯Ì¬´´½¨"(ÏÂÒ»Õ½Ú)Öл¹»áÓõ½£¬Ëü±»µ¥¶À¶¨Î»Ò»¸öºê¡£RUNTIME_CLASS(class_name) ºêºÜ¼òµ¥¾ÍÊÇ·µ»Ø class_name ÖÐµÄ RuntimeClass ½á¹¹ÌåµÄµØÖ·¡£IMPLEMENT_RUNTIMECLASS ºê¾ÍÊÇÌî³ä class_name ÖÐµÄ RuntimeClass ½á¹¹Ìå²¢ÇÒ¸²¸Ç GetRuntimeClass()·½·¨¡£¼ÙÈçÎÒÃÇÕâôµ÷ÓÃ:
IMPLEMENT_DYNAMIC(CCmdTarget,CObject)
ºêÌæ»»ºóµÄ½á¹ûΪ:
const CRuntimeClass classCCmdTarget =
{ CCmdTarget,sizeof(class CCmdTarget),
0xFFFF,NULL, ((CRunt CRuntimeClass*
CCmdTarget::GetRuntimeClass()
const { return ((CRuntimeClass*)
(&CCmdTarget::classCCmdTarget));
}
|
ǰһ¶ÎΪ CRuntimeClass ½á¹¹µÄÌî³ä£¬ºóÒ»¶ÎΪ GetRuntimeClass() µÄʵÏÖ¡£
4.IsKindOf(ÀàÐÍʶ±ð) ʵÏÖ
µ±Äã¿´µ½ÕâÀRTTI µÄʵÏÖÆäʵÒѾʵÏÖÁË£¬Ê£ÏµľÍÊǵ÷ÓÃÕâЩºê¾ÍÊÇÁË£¬ºÜ¼òµ¥£¬Ö»ÐèÒªÔÚʵÏÖ RTTI µÄÀàµÄÉùÃ÷ÖмÓÈë DECLARE_DYNAMIC ºê£¬ÔÚʵÏÖÎļþÖмÓÈë IMPLEMENT_DYNAMIC ºê£¬×îºóдһ¸ö IsKindOf() º¯Êý¾Í´ó¹¦¸æ³ÉÁË¡£
IsKindOf() º¯ÊýºÜ¼òµ¥£¬ÈçÏÂËùʾ:
BOOL CObject::IsKindOf
(const CRuntimeClass* pClass)const
{
CRuntimeClass* pClassThis =
GetRuntimeClass();
while(pClassThis != NULL)
{
if(pClassThis == pClass)
{
coutGetRuntimeClass()->m_lpszClassName
is "pClass->m_lpszClassNameendl;
return TRUE;
}
pClassThis = pClassThis->m_pBaseClass;
}
coutGetRuntimeClass()->m_lpszClassName"
is not "pClass->m_lpszClassNameendl;
return FALSE;
}
|
ÈôÕâôµ÷ÓÃ:
A a;
a.IsKindOf(RUNTIME_CLASS(B));
Ôò»á½« A ÀàÒÔ¼° A µÄ¸¸Àà(ͨ¹ý m_pBaseClass Ö¸ÕëÖð¼¶ÍùÉÏ)µÄ CRuntimeClass µÄµØÖ·Óë B ÀàµÄ CRuntimeClass µÄµØÖ·½øÐбȽϲ¢·µ»Ø±È½Ï½á¹û£¬ÕâÀïÎÒ¸ù¾Ý·µ»Ø½á¹û¼ÓÈëÁËÒ»¾äÊä³ö·½±ã²é¿´¡£
Ïà¶ÔÓÚÉÏÒ»Õ½ڵĴúÂ룬ֻ¸Ä¶¯ÁË 5 ¸öÎļþ£¬ÒÀ´ÎÈçÏÂ:
1.afx.h
¼ÓÈëÁËÀàÐÍÉùÃ÷:
class CObject;
struct CRuntimeClass;
struct AFX_CLASSINIT;
Ìí¼ÓÁËÔ¤¶¨Òå:
#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;
Ìí¼ÓÁËǰ 3 ²¿·ÖÖеÄËùÓÐÄÚÈÝ£¬ËùÓеĺ꣬ËùÓеÄÊý¾Ý½á¹¹¡£
ÓÉÓÚ»ùÀà CObject ûÓи¸À࣬Òò´ËÊÖ¶¯Ìí¼ÓÁË Cobject ÀàµÄ GetRuntimeClass()º¯ÊýÉùÃ÷£¬CRuntimeClass ½á¹¹ÌåÉùÃ÷¡£»¹Ìí¼ÓÁË IsKindOf() º¯Êý¡£´úÂëÈçÏÂ:
[cpp] view plain copy
ÔÚCODEÉϲ鿴´úÂëÆ¬ÅÉÉúµ½ÎҵĴúÂëÆ¬//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;
};
|
2.afx.cpp
Ìí¼ÓÁË CObject ÐÂÔöº¯ÊýµÄʵÏÖ¡£CObject::CR
untimeClass µÄÌî³ä¡£AfxClassInit µÄʵÏÖ(¿Õ)¡£´úÂëÈçÏÂ:
3.afxwin.h
ÔÚËùÓÐÀàÖмÓÈëÁË DECLARE_DYNAMIC ºê¡£´úÂëÈçÏÂ:
//afxwin.h
#pragma once
#include "afx.h"
//CCmdTargetÀàÉùÃ÷
class CCmdTarget : public CObject
{
DECLARE_DYNAMIC(CCmdTarget)
public:
CCmdTarget();
};
//CDocumentÀàÉùÃ÷
class CDocument : public CCmdTarget
{
DECLARE_DYNAMIC(CDocument)
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)
public:
CView();
};
//CWinThreadÀàÉùÃ÷
class CWinThread : public CCmdTarget
{
DECLARE_DYNAMIC(CWinThread)
public:
CWnd* m_pMainWnd;
CWinThread();
virtual BOOL InitInstance();
virtual int Run();
};
//CWinAppÀàÉùÃ÷
class CWinApp : public CWinThread
{
DECLARE_DYNAMIC(CWinApp)
public:
CWinApp();
virtual BOOL InitApplication();
virtual BOOL InitInstance(); //¸²¸Ç
virtual int Run(); //¸²¸Ç
};
|
4.afxwin.cpp
¼ÓÈëÁËËùÓÐÀàµÄ IMPLEMENT_DYNAMIC ºê¡£´úÂëÈçÏÂ:
//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; }
|
5.My.cpp
ÔÚ main() º¯ÊýÖÐÔö¼ÓÁË IsKindOf() º¯ÊýµÄ²âÊÔ´úÂë¡£
´úÂëÈçÏÂ:
//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;
coutendl; 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;
}
|
³ÌÐòÔËÐнá¹ûÈçÏÂ:
//¹¹Ô캯ÊýµÄÊä³öÒѾʡÂÔ
COBject is not CCmdTarget
CCmdTarget is COBject
CView is CCmdTarget
CWinApp is COBject
CWnd is not CWinThread |