-
CRuntimeClass
鎖定
CRuntimeClass簡介
CRuntimeClass是MFC實現的RTTI(運行時類型信息),MFC中的很多類需要由框架動態創建(比如文檔、視圖、框架窗口類等等),所以從CObject繼承的類如果需要這種能力,必須實現它的CRuntimeClass,包括CreateObject靜態方法(這個方法簡單調用new CMyClass)。而做到這個很簡單,使用DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏就自動擁有這個特性,看看這兩個宏的定義就能理解其原理。
CRuntimeClass在MFC中定義為一個數據結構,在文件AFX.H中聲明,它是用來串起MFC從COBJECT繼承下來的所有類(相當於一根繩,只要你牽住繩的一頭你就可以得到繩上的所有數據),你也可以把你自己寫的類加入這根繩。
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注意
:
要使用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的介紹是比較少的,在這裏總結它的一些用法。
CRuntimeClass動態確定類
在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,避免強制轉換帶來的錯誤 }
CRuntimeClass生成類
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後方可生效。
- 參考資料
-
- 1. CRuntimeClass的結構與功能 .c博客[引用日期2015-04-22]
- 詞條統計
-
- 瀏覽次數:次
- 編輯次數:16次歷史版本
- 最近更新: lijia19890223