有些东西能够农明白所以然,有些不能弄明白(比如:原子弹是什么蛋?);我要做的就是把能弄明白的弄明白。别让明白的也不明白,不明白的更不明白。
#define DECLARE_DYNAMIC(class_name) /
public: /
static const AFX_DATA CRuntimeClass class##class_name; /
virtual CRuntimeClass* GetRuntimeClass() const; /
#define AFX_DATA AFX_CORE_DATA
#ifndef AFX_CORE_DATA
#define AFX_CORE_DATA AFX_DATA_IMPORT
#define AFX_CORE_DATADEF
#endif
#ifndef AFX_DATA_IMPORT
#define AFX_DATA_IMPORT __declspec(dllimport)
#endif
#if defined(_AFXEXT) && !defined(_AFXDLL)
#define _AFXDLL
#endif
// 原来只是多了个函数
define IMPLEMENT_DYNAMIC(class_name, base_class_name) /
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL)
#ifdef _AFXDLL
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) /
CRuntimeClass* PASCAL class_name::_GetBaseClass() /
{ return RUNTIME_CLASS(base_class_name); } /
AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { /
#class_name, sizeof(class class_name), wSchema, pfnNew, /
&class_name::_GetBaseClass, NULL }; /
CRuntimeClass* class_name::GetRuntimeClass() const /
{ return RUNTIME_CLASS(class_name); } /
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) /
CRuntimeClass* PASCAL class_name::_GetBaseClass() /
{ return RUNTIME_CLASS(base_class_name); } /
AFX_COMDAT AFX_DATADEF CRuntimeClass class_name::class##class_name = { /
#class_name, sizeof(class class_name), wSchema, pfnNew, /
&class_name::_GetBaseClass, NULL }; /
CRuntimeClass* class_name::GetRuntimeClass() const /
{ return RUNTIME_CLASS(class_name); } /
#else
#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) /
AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { /
#class_name, sizeof(class class_name), wSchema, pfnNew, /
RUNTIME_CLASS(base_class_name), NULL }; /
CRuntimeClass* class_name::GetRuntimeClass() const /
{ return RUNTIME_CLASS(class_name); } /
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) /
AFX_DATADEF CRuntimeClass class_name::class##class_name = { /
#class_name, sizeof(class class_name), wSchema, pfnNew, /
RUNTIME_CLASS(base_class_name), NULL }; /
CRuntimeClass* class_name::GetRuntimeClass() const /
{ return RUNTIME_CLASS(class_name); } /
#endif
#define AFX_COMDAT
#define AFX_DATADEF
#define AFX_DATA AFX_CORE_DATA
/
// Basic object model
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;
// 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
};
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
在候捷的 深入浅出MFC 中还有:
struct AFX_CLASSINIT
{ AFX_CLASSINIT(CRuntimeClass* pNewClass); };
这个暂时没有弄明白,在VC 中翻原代码没有翻到,我会继续查的
总之我的感觉,这是在给加了这个宏的代码中加入了一个静态成员函数,而CRuntimeClass 这个结构的建立就是一个有表头指针的单链表,方便的实现了RTTI
------------------------------------我是分隔线------------------------------------------------------------------
活着时要尽量开心,因为你会死很久(盗用他人签名)
石头
2006/8/6