CRuntimeCla
此結構具有下列
成員
:
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的介紹是比較少的,在這裡總結它的一些用法。
1、動態確定類
在MFC中CObject::IsKindOf( const CRuntimeClass* pClass ) 利用CRuntimeClass來進行判定,如果你生成的類是以CObject為基礎的,你可以使用該成員函式來判定。下面舉一個例子來加深了解。
class CAge:public CObject
BOOL 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,避免強制轉換帶來的錯誤
}
2、生成類
CObject CRuntimeClass::CreateObject(void)可以產生一個類變數。作用和new類似,但在某些特殊場合有獨特的作用。下面舉一個例子來加深了解。
假定有以下幾個類定義
class CWndA: public CWnd
class CWndB: public CWnd
function1()
{
CRuntimeClass* pC=RUNTIME_CLASS( CWndA );
CreateWnd(pC);
}
CWnd* CreateWnd(CRuntimeClass* pClass)
{
return (CWnd*)pClass->CreateObject();
}
在上面例子中,CreateWnd返回的是CWnd* 其實它是一個CWndA*。你可以進行由父類到子類的強制轉換而不必要擔心出錯。使用CRuntimeClass可以代替使用switch生產類實例的一些繁瑣。(請好好想想它的用途,當你發現它的好處時,你一定會大吃一驚,M$使用宏來實現類的動態檢測,如果誰有興趣可以去看看MFC的原始碼。)
注意:在類的定義中使用IMPLEMENT_DYNCREATE後方可生效。