DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC宏

IMPLEMENT_DYNAMIC是實現“運行時類型識別”宏,與之相對應的是DECLARE_DYNAMIC(聲明“運行時類型識別”宏)。也 就是說你在.CPP文件中如果看見有IMPLEMENT_DYNAMIC,則在.H文件中必定有DECLARE_DYNAMIC的聲明。
DECLARE_DYNAMIC/DEClARE_DYNAMIC是爲了確定運行時對象屬於哪一個類而定義的宏。
DEClARE_DYNCREATE/IMPLEMENT_DYNCREATE是爲了“動態創建"類的實例而定義的宏。new可以用來創建對象,但不是動態的。比如說,你要在程序中實現根據擁護輸入的類名來創建類的實例,下面的做法是通不過的:
char szClassName[60];
cin >> szClassName;
CObject* pOb=new szClassName; //通不過
這裏就要用到DEClARE_DYNCREATE/IMPLEMENT_DYNCREATE定義的功能了。

定義:

//////////////////////////////////////////////////////////////////////////////
// Helper macros for declaring CRuntimeClass compatible classes

#ifdef _AFXDLL
#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 _DECLARE_DYNAMIC(class_name) /
protected: /
    static CRuntimeClass* PASCAL _GetBaseClass(); /
public: /
    static CRuntimeClass class##class_name; /
    static CRuntimeClass* PASCAL GetThisClass(); /
    virtual CRuntimeClass* GetRuntimeClass() const; /

#else
#define DECLARE_DYNAMIC(class_name) /
public: /
    static const CRuntimeClass class##class_name; /
    virtual CRuntimeClass* GetRuntimeClass() const; /

#define _DECLARE_DYNAMIC(class_name) /
public: /
    static CRuntimeClass class##class_name; /
    virtual CRuntimeClass* GetRuntimeClass() const; /

#endif

引用:

DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC

#define DECLARE_DYNAMIC(class_name)/   
public:/
    static CRuntimeClass class##class_name;/
    //聲明一個類型爲CRuntimeClass的靜態public成員變量,變量名是由字符串"class"
    //與所指定的類的類名組成。舉例而言,如果你寫DECLARE_DYNAMIC(CMyView),則等於聲明瞭一個
    // static CRuntimeClass classCMyView靜態變量

    virtual CRuntimeClass* GetRuntimeClass() const;/
    //聲明一個虛函數,函數名爲GetRuntimeClass,返回值爲CRuntimeClass類型的指針
    //無參數,並且是個const函數

#define IMPLEMENT_DYNAMIC(class_name,bass_class_name)/
       _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL)

#define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew)/
    static char _lpsz##class_name[]= #class_name;/
    //定義一個C類型字符串靜態變量,變量名由"_lpsz"和指定類的類名組成,變量值爲該指定類型的名字
    //比如是CMyView,那麼定義的就是static char _lpszCMyView="CMyView";

    CRuntimeClass class_name::class##class_name = {/
        _lpsz##class_name,sizeof(class_name),wSchema,pfnNew,/
            RUNTIME_CLASS(base_class_name),NULL};/
    //給之前在DECLARE_DYNAMIC裏定義的CRuntimeClass類型的靜態成員變量賦值
    //當然,除最後一個m_pNextClass沒有賦值(賦值爲NULL,它由下面的結構處理)

    static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);/
    //初始化一個名爲"_init_##class_name"的AFX_CLASSINIT靜態結構,主要作用是給指定的class_name的
    //class##class_name靜態變量的最後一個成員m_pNextClass賦值,具體見下面解釋AFX_CLASSINIT中

    CRuntimeClass* class_name::GetRuntimeClass() const/
        { return &class_name::class##class_name;}/
    //之前在DECLARE_DYNAMIC裏定義的GetRuntimeClass的實現,很簡單,就一個return語句。

#define RUNTIME_CLASS(class_name)/
        (&class_name::class##class_name)
//這部分之所以單獨define出一個宏,主要是爲了方便從某個指定的class直接得到它的CRuntimeclass靜態成員

//以下是解釋AFX_CLASSINIT結構,注意,這不是一個宏
//爲了看得更加清楚,我按照struct定義的慣常格式來寫這個struct的定義
struct AFX_CLASSINIT {
    AFX_CLASSINIT(CRuntimeClass *pNewClass);
};

AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass *pNewClass)
{
    pNewClass->m_pNextClass = CRuntimeClass::pFirstClass;
    //讓m_pNextClass指向pFirstClass所指的CRuntimeClass變量

    CRuntimeClass::pFirstClass = pNewClass;
    //讓pFirstClass指向pNewClass所指的變量,也就是本class的CRuntimeClass靜態變量
}

發佈了21 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章