MFC的CObject基类定义有public的virtual CRuntimeClass *GetRuntimeClass() const;是用来返回多态运行时类信息的虚方法,将运行时类信息封装进了结构体CRuntimeClass中
// class CObject is the root of all compliant objects
class AFX_NOVTABLE CObject
{
public:
// Object model (types, destruction, allocation)
virtual CRuntimeClass* GetRuntimeClass() const;
virtual ~CObject() = 0; // virtual destructors are necessary
// Diagnostic allocations
void* PASCAL operator new(size_t nSize);
void* PASCAL operator new(size_t, void* p);
void PASCAL operator delete(void* p);
void PASCAL operator delete(void* p, void* pPlace);
#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
// for file name/line number tracking using DEBUG_NEW
void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
void PASCAL operator delete(void *p, LPCSTR lpszFileName, int nLine);
#endif
// Disable the copy constructor and assignment by default so you will get
// compiler errors instead of unexpected behaviour if you pass objects
// by value or assign objects.
protected:
CObject();
private:
CObject(const CObject& objectSrc); // no implementation
void operator=(const CObject& objectSrc); // no implementation
// Attributes
public:
BOOL IsSerializable() const;
BOOL IsKindOf(const CRuntimeClass* pClass) const;
// Overridables
virtual void Serialize(CArchive& ar);
#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Implementation
public:
static const CRuntimeClass classCObject; //类的静态属性,类属性,包含当前类的类名的CRuntimeClass结构体
#ifdef _AFXDLL
static CRuntimeClass* PASCAL _GetBaseClass();
static CRuntimeClass* PASCAL GetThisClass();
#endif
};
结构体CRuntimeClass最直接的内容就是运行时类的类名LPCSTR m_lpszClassName:
struct CRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _AFXDLL
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CRuntimeClass* m_pBaseClass;
#endif
// Operations
CObject* CreateObject();
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;
// dynamic name lookup and creation
static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName);
static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName);
static CObject* PASCAL CreateObject(LPCSTR lpszClassName);
static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);
// Implementation
void Store(CArchive& ar) const;
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);
// CRuntimeClass objects linked together in simple list
CRuntimeClass* m_pNextClass; // linked list of registered classes
const AFX_CLASSINIT* m_pClassInit;
};
class DerivedClass:public CObject
{
DECLARE_DYNAMIC(DerivedClass);
//剩余类定义
}
所有派生自CObject基类的类可以在类内使用MFC提供的宏“DECLARE_DYNAMIC(DeriveClass);”自动实现静态方法_GetBaseClass()、静态属性class_name、静态方法GetThisClass()和虚方法virtual CRuntimeClass* GetRuntimeClass() const;的定义:
#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
派生类实例可以调用GetRuntimeClass()虚方法得到运行时类的信息,最重要的是运行时类类名:
BaseClass *pobj=new DerivedClass();
CRuntimeClass *pRunClass=pobj->GetRuntimeClass(); //DerivedClass的CRuntimeClass
std::string strRunClass = pRunClass->m_lpszClassName;//"DerivedClass"
CObject cobj=CObject();
bool bBaseClass = pRunClass->IsDerivedFrom(cobj.GetRuntimeClass()); //确定派生链上的基类
//以及根据指定类名(派生自CObject基类的)创建实例并返回一个指向该实例的CObject基类指针:
CObject *pcobj=pobj->CreateObject((LPCSTR)strRunClass);
//以及返回指定类名的类的CRuntimeClass结构体:
CRuntimeClass *pRunClass2=pRunClass->FromName((LPCSTR)_T("DerivedClass"));
//以及获取直接基类与当前类的CRuntimeClass结构体指针:
//CRuntimeClass *pBaseClass = pRunClass->_GetBaseClass();
CRuntimeClass *pBaseClass = pRunClass->m_pfnGetBaseClass(); //获取指针类型
CRuntimeClass *pThisClass = obj.GetThisClass(); //获取指针类型
//以及派生自当前类的派生类的CRuntimeClass结构体指针:
CRuntimeClass *pNextClass = pRunClass->m_pNextClass; //没有就是nullptr