CRuntimeClass

CRuntimeClass沒有基類。 每個由CObject派生的類都與一個CRuntimeClass結構相聯繫,用戶可以使用該結構獲取一個對象及其基類的運行時信息。當需要額外的函式參數檢查時,或當用戶必須根據一個對象的類編寫特殊目的代碼時,在運行時確定該對象的類就非常有用。C++並不直接支持運行時類的信息。

基本介紹

  • 中文名:CRuntimeClass
  • 特點:沒有基類
  • 相關:與一個CRuntimeClass結構相聯繫
  • 功能:獲取對象及其基類的運行時信息
簡介:,CRuntimeClass,注意,動態確定類,生成類,

簡介:

CRuntimeClass是MFC實現的RTTI(運行時類型信息),MFC中的很多類需要由框架動態創建(比如文檔、視圖、框架視窗類等等),所以從CObject繼承的類如果需要這種能力,必須實現它的CRuntimeClass,包括CreateObject靜態方法(這個方法簡單調用new CMyClass)。而做到這個很簡單,使用DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏就自動擁有這個特性,看看這兩個宏的定義就能理解其原理。
CRuntimeClass在MFC中定義為一個數據結構,在檔案AFX.H中聲明,它是用來串起MFC從COBJECT繼承下來的所有類(相當於一根繩,只要你牽住繩的一頭你就可以得到繩上的所有數據),你也可以把你自己寫的類加入這根繩。
每個從CObject中派生的類都有一個CRuntimeClass對象同它關聯以完成在運行時得到類實例的信息或者是它的基類。

CRuntimeClass

此結構具有下列成員:
LPCSTR m_lpszClassName     存放ASCII類名的以空字元結尾的字元串。int m_nObjectSize    以位元組為單位給出對象的大小。若此對象具有指向被分配的記憶體的數據成員,則此值不包含該記憶體的大小。UINT m_wSchema    分類編號(對不可分類的類,該值為-1)。對於此分類編號的詳細說明,參見IMPLEMENT_SERIAL宏。CObject* ( PASCAL* m_pfnCreateObject )    是一個指向預設的構造函式的函式指針,該構造函式創建一個你的類的對象(只有在類支持動態創建時才有    效;否則,返回NULL)。CRuntimeClass* ( PASCAL* m_pfn_GetBaseClass )( )    如果你的應用程式是動態地連結到MFC的AFXDLL版本,則是一個指向函式的指針,該函式返回基類的    CRuntimeClass結構。CRuntimeClass* m_pBaseClass    如果你的應用程式是靜態地連結到MFC的,則是一個指向基類的CRuntimeClass結構的指針。Feature Only in Professional and Enterprise Editions     只有在Visual C++的專業版和企業版中才支持對MFC的靜態連結。CObject* CreateObject( );    從CObject派生的類可以支持動態創建,這是在運行時創建一個指定類的對象的能力。例如,文檔,視圖和    框架類就應該支持動態創建。CreateObject成員函式可以用來實現這個功能,在運行時為這些類創建對象。BOOL IsDerivedFrom( const CRuntimeClass* pBaseClass) const;    如果IsDerivedFrom類成員的類是從基類派生而來,該基類的CRuntimeClass結構作為一個參數給出,則返    回 TRUE。IsDerivedFrom從該成員的類開始向上沿派生類鏈經過所有的類直到頂端,並且只有在沒有與    基類匹配 的類時才返回FALSE。

注意

要使用CRuntimeClass結構,你必須在你想要獲取運行時對象信息的類的實現中包括IMPLEMENT_DYNAMIC,IMPLEMENT_DYNCREATE,或IMPLEMENT_SERIAL宏。
請參閱:
CObject::GetRuntimeClass, CObject::IsKindOf, RUNTIME_CLASS, IMPLEMENT_DYNAMIC, IMPLEMENT_DYNCREATE, IMPLEMENT_SERIALCRuntimeClass在MFC中的作用很重要,因為MFC利用它來進行類的動態確定,即是通過類變數來判定該變數是否為某一類的實例。由於指針的類型是可以轉換的,所以時常會出現從A到B的轉換導致錯誤。而在MFC的各種書籍中對CRuntimeClass的介紹是比較少的,在這裡總結它的一些用法。

動態確定類

在MFC中CObject::IsKindOf( const CRuntimeClass* pClass ) 利用CRuntimeClass來進行判定,如果你生成的類是以CObject為基礎的,你可以使用該成員函式來判定。下面舉一個例子來加深了解。
class CAge : public CObjectBOOL IsAge(CObject* pO){    return pO->IsKindOf( RUNTIME_CLASS( CAge ) );}    BOOL IsAge2(CAge* pO){    return pO->IsKindOf( RUNTIME_CLASS( CAge ) );}void main(void){    CObject a;    CAge b;    IsAge(&a);//return FALSE    IsAge(&b);//return TRUE    IsAge2((CAge*)&a);//return FALSE,避免強制轉換帶來的錯誤}

生成類

CObject CRuntimeClass::CreateObject(void)可以產生一個類變數。作用和new類似,但在某些特殊場合有獨特的作用。下面舉一個例子來加深了解。
假定有以下幾個類定義
class CWndA: public CWndclass CWndB: public CWndfunction1(){     CRuntimeClass* pC=RUNTIME_CLASS( CWndA );    CreateWnd(pC);}CWnd* CreateWnd(CRuntimeClass* pClass){    return (CWnd*)pClass->CreateObject();}
在上面例子中,CreateWnd返回的是CWnd* 其實它是一個CWndA*。你可以進行由子類到父類的強制轉換而不必要擔心出錯。使用CRuntimeClass可以代替使用switch生產類實例的一些繁瑣。(請好好想想它的用途,當你發現它的好處時,你一定會大吃一驚,M$使用宏來實現類的動態檢測,如果誰有興趣可以去看看MFC的原始碼。)
注意:在類的定義中使用IMPLEMENT_DYNCREATE後方可生效。

相關詞條

熱門詞條

聯絡我們