MFC中动态创建DECLARE_DYNCREATE和运行时类型识别DECLARE_DYNAMIC

DECLARE_DYNCREATE:支持动态创建
DECLARE_DYNAMIC:支持运行时类型识别(RTTI)
凡是支持动态创建的,一定支持RTTI。

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

#define DECLARE_DYNAMIC(class_name) \
protected: \
    static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
    static const CRuntimeClass class##class_name; \
    static CRuntimeClass* PASCAL GetThisClass(); \
    virtual CRuntimeClass* GetRuntimeClass() const; \
#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, NULL)

#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \
    CRuntimeClass* PASCAL class_name::_GetBaseClass() \
        { return RUNTIME_CLASS(base_class_name); } \
    AFX_COMDAT const CRuntimeClass class_name::class##class_name = { \
        #class_name, sizeof(class class_name), wSchema, pfnNew, \
            &class_name::_GetBaseClass, NULL, class_init }; \
    CRuntimeClass* PASCAL class_name::GetThisClass() \
        { return _RUNTIME_CLASS(class_name); } \
    CRuntimeClass* class_name::GetRuntimeClass() const \
        { return _RUNTIME_CLASS(class_name); }

#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())

#define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))

所以:

// MainFrm.h 
DECLARE_DYNCREATE(CMainFrame)
翻译为
DECLARE_DYNAMIC(CMainFrame)
static CObject* PASCAL CreateObject();
最终翻译为
protected: 
    static CRuntimeClass* PASCAL _GetBaseClass(); 
public: 
    static const CRuntimeClass classCMainFrame; 
    static CRuntimeClass* PASCAL GetThisClass(); 
    virtual CRuntimeClass* GetRuntimeClass() const; 
        static CObject* PASCAL CreateObject();

// MainFrm.cpp
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
翻译为
CObject* PASCAL CMainFrame::CreateObject() 
        { return new CMainFrame; } 
IMPLEMENT_RUNTIMECLASS(CMainFrame, CFrameWnd, 0xFFFF, CMainFrame::CreateObject, NULL)
最终翻译为
CObject* PASCAL CMainFrame::CreateObject() 
        { return new CMainFrame; } 
CRuntimeClass* PASCAL CMainFrame::_GetBaseClass() 
        { return CMainFrame::GetThisClass(); } 
AFX_COMDAT const CRuntimeClass CMainFrame::classCMainFrame= { "CMainFrame", sizeof(class MainFrame), wSchema, pfnNew, &CMainFrame::_GetBaseClass, NULL, class_init }; 
CRuntimeClass* PASCAL CMainFrame::GetThisClass() 
        { return (CRuntimeClass*)(&CMainFrame::classCMainFrame); } 
CRuntimeClass* CMainFrame::GetRuntimeClass() const 
        { return (CRuntimeClass*)(&CMainFrame::classCMainFrame);; }

 

宏定义中 #:表示字符串  ##:表示连接

在用#define 定义时 , 斜杠("\")是用来续行的,

"#"用来把参数转换成字符串,是给参数加上双引号。
"##"则用来连接前后两个参数,把它们变成一个参数,
"#@"是给参数加上单引号。下面的例子会使您很容易理解。
#define CAT(x,y)           x##y       /* CAT("1","abc") => "1abc" CAT(1, 34) => 134 */
#define TOCHAR(a)     #@a       /* TOCHAR(1) => '1' */
#define TOSTRING(x)     #x      /* TOSTRING(1) => "1" */

猜你喜欢

转载自www.cnblogs.com/htj10/p/11831404.html
今日推荐