IMPLEMENT_DYNCREATE 動態創建機制

動態創建機制

在CRuntimeClass結構中加入了兩個元素
CObject* CreateObject()函數和static CRuntimeClass PASCAL Load()
於是又多了兩個宏
DECLARE_DYNCREATE宏和IMPLEMENT_DYNCREATE宏
#define DECLARE_DYNCREATE(class_name)\
      DECLARE_DYNAMIC(class_name)\
      static Cobject* PASCAL CreateObject();


#define IMPLEMENT_DYNCREATE(class_name,base_class_name)\
      CObject* PASCAL class_name::CreateObject()\
      {returnnew class_name;}
      _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,\
      class_name::CreateObject)
由上可知,DECLARE_DYNCREATE是DECLARE_DYNAMIC的增強版,也就是說,擁有動態創建能力的類庫,必然亦有運行時類型識別能力
class CFrameWnd:public CWnd
{
DECLARE_DYNCREAT(CFrameWnd)
};
IMPLEMENT_DYNCREATE(CFrameWnd,CWnd)

於是被展開如下
class CFrameWnd:public CWnd
{
public:
static CRuntimeClass classCFrameWnd;
virtual CRuntimeClass* GetRuntimeClass() const;
static CObject* PASCAL CreateObject();
}


CObject* PASCAL CFrameWnd::CreateObject()
{return new CFrameWnd;}
static char _lpszCFrameWnd[]="CFrameWnd";
CRuntimeClass CFrameWnd::classCFrameWnd={
_lpszCFrameWnd,sizeof(CFrameWnd),0xFFFF,CFrameWnd::CreateObject,RUNTIME_CLASS(CWnd),NULL};
staitc AFX_CLASSINIT _init_CFrameWnd(&CFrameWnd::classCFrameWnd);
CRuntimeCLass* CFrameWnd::GetRuntimeClass() const
    {return &CFrmaeWnd::classCFrameWnd;}
這個類所有的結構中的m_pfnCreateObject不再爲NULL,而是被賦予函數指針CFrameWnd::CreateObject,而用DECLARE_DYNAMIC來聲明時這個函數指針被賦值NULL,因爲DECLARE_DYNAMIC不具有動態創建功能,所以這個創建函數指針爲NULL
在main()函數中加上這一段代碼
void main()
{
CRuntimeClass* pClassRef;
CObject* pOb;
while(1)
if((pClassRef=CRAuntimeClass::Load())==NULL)
break;//只有當CRAuntimeClass::Load()傳回NULL時,while循環纔會停止
pOb=pClassRef->createObject();
if(pOb!=NULL)
pOb->SayHello();
}

CObject* CRuntimeClass::CreateObject()
{
if(m_pfnCreateObject==NULL)
{
TRACE1("ERROR:Trying to create objcet which is not"
     "DECLARE_DYNCREATE nor DECLARE_SERIAL:%HS\n",m_lpszClassName);
return NULL;
CObject* pObject=NULL;
pObject=(*m_pfnCreateObject)();
return pObject;
}


CObject* pObject=NULL;
pObject= (*m_pfnCreateObject)();
return pObject;
}
這個函數先檢查結構中的m_pfnCreateObject是否爲空,爲空則不能創建對象,凡是m_pfnCreateObject不爲NULL者,即可動態創建,若不爲空,則利用m_pfnCreateObject所指向的函數來創建一個對象的指針。
CRuntimeClass* PASCALCRuntimeClass::Load()
{
char szClassName[64];
CRuntimeCLass* pClass;
cout<<"enter a class name:"<<endl;
cin>>szClassName;
for(pClass=pFirstClass;pClass!=NULL;pClass=pClass->m_pNextClass)
{
if(strcmp(szClassName,pClass->m_lpszClassName)==0;
return pClass;
}
TRACE1("ERROR:class not found:%s \n",szClassName;
return NULl;
}
這個函數首先需要輸入一個類名,CRuntimeCLass* pClass這條代碼聲明瞭一個結構的指針,然後利用這個指針來遍歷鏈表
當找到和這個類名相同的類時,則返回這個類的結構的指針,即pClass。


這其中有幾個creat函數,共有三個,其聯繫如下
在結構中有:
CObject* (PASCAL* m_pfnCreateObject)();稱爲函數一
CObject* CreateObject();函數二
在類中有static CObject* PASCAL CreateObject();函數三

基中,函數一是用來記錄函數三的指針的,因爲想要訪問這個類時可以獲得的只有這個類的結構指針而以
函數二則是通過調用函數一來實現創建對象的,並且在函數二中還要對m_pfnCreateObject進行檢查是否爲NULL

函數三在類定義中,如上面的
CObject* PASCAL CFrameWnd::CreateObject()
{return new CFrameWnd;}
返回的是一個當前類對象的指針

通過以上方式可以看到,要動態創建一個類對象,有如下幾個步驟
1.類說明中使用DECLARE_DYNCREATE(CLASSNMAE)宏;和在類的實現文件中使用IMPLEMENT_DYNCREATE(CLASSNAME,BASECLASS)宏;這個宏完成構造CRuntimeClass對象,並加入到鏈表中。

2、使用時先通過宏RUNTIME_CLASS得到類的RunTime信息,當獲得一個類名時,先用類別型錄網判別這個類是否是鏈表中有的類,若是,就使用CRuntimeClass的成員函數CreateObject創建一個該類的實例。
3、CObject* pObject = pRuntimeClass->CreateObject();//完成動態創建

 

轉自:http://blog.sina.com.cn/s/blog_53b6bdf80100nzll.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章