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 默认构造函数的函数指针,创建一个类的对象,抽象类则返回NULL
#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 next指针
const AFX_CLASSINIT* m_pClassInit;
};
类别型录网
DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏
#define DECLARE_DYNAMIC(class_name) \
public: \
static const CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL, NULL)
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew, class_init) \
AFX_COMDAT const CRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
RUNTIME_CLASS(base_class_name), NULL, class_init }; \
CRuntimeClass* class_name::GetRuntimeClass() const \
{ return RUNTIME_CLASS(class_name); } \
#define AFX_COMDAT __declspec(selectany)
#define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name)
#define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
值得注意的是:CRuntimeClass结构体的静态成员pFirstClass指针属于类,所以从一开始它就记录了所有生成的类的类别型录,整个程序中仅此一份,于是便可方便的进行IsKindOf操作。如下:
void PrintAllClasses()
{
CRuntimeClass* pClass;
for(pClass = CRuntimeClass::pFirstClass; pClass!=NULL;pClass = pClass->m_pNextClass)
{
cout << pClass->m_lpszClassName << "\n";
cout << pClass->m_nObjectSize << "\n";
cout << pClass->m_wSchema << "\n";
}
}
注意,while循环所追踪的是“同宗”路线,也就是凭借着m_pBaseClass而非m_pNextClass。