在MFC的学习及使用中,有一些基础的类必须了解清楚,甚至其中的一些特点等。首先我们来看其中最重要、最基本的一个CObject类。
CObject是大多数MFC类的根类或基类。CObject类有很多有用的特性:对运行时类信息的支持,对动态创建的支持,对串行化的支持,对象诊断输出,等等。MFC从CObject派生出许多类,具备其中的一个或者多个特性。程序员也可以从CObject类派生出自己的类,利用CObject类的这些特性。
相关的特性实现:
CRuntimeClass结构,
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
CRuntimeClass* m_pBaseClass;
CObject* CreateObject();
static CRuntimeClass* PASCAL Load(); // CRuntimeClass objects linked together in simple list
static CRuntimeClass* pFirstClass; // start of class list
CRuntimeClass* m_pNextClass; // linked list of registered classes
};
m_pfnCreateObject,将被初始化指向所在类的静态成员函数CreateObject。CreateObject函数在初始化时由实现宏定义m_pfnGetBaseClass,如果定义了_AFXDLL,则该变量将被初始化指向所在类的成员函数
_GetBaseClass。_GetBaseClass在声明宏中声明,在初始化时由实现宏定义
RUNTIME_CLASS宏定义:
#define RUNTIME_CLASS(class_name) /
(&class_name::class##class_name)
返回对类class_name的CRuntimeClass类型成员变量的引用,该成员变量的名称是“class”加上class_name(类的名字)。例:
RUNTIME_CLASS(CObject)得到对classCObject的引用;
动态声明:
#ifdef _AFXDLL //动态链接到MFC DLL
#define DECLARE_DYNAMIC(class_name) /
protected: /
static CRuntimeClass* PASCAL _GetBaseClass(); /
public: /
static const AFX_DATA CRuntimeClass class##class_name; /
virtual CRuntimeClass* GetRuntimeClass() const; /
#else
#define DECLARE_DYNAMIC(class_name) /
public: /
static const AFX_DATA CRuntimeClass class##class_name; /
virtual CRuntimeClass* GetRuntimeClass() const; /
#define _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) /
static char _lpsz##class_name[] = #class_name; /
CRuntimeClass class_name::class##class_name = { /
_lpsz##class_name, sizeof(class_name), wSchema, pfnNew, /
RUNTIME_CLASS(base_class_name), NULL }; /
static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name); /
CRuntimeClass* class_name::GetRuntimeClass() const /
{ return &class_name::class##class_name; } /
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) /
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL)
运行时类支持实现:以CCmdTarger为例
在CCmdTarget.h中:
class CCmdTarget : public CObject
{
DECLARE_DYNAMIC(CCmdTarget);
public:
CCmdTarget();
}
在.c文件中
IMPLEMENT_DYNAMIC(CCmdTarget,CObject);
经过DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC宏处理:
DECLARE_DYNAMIC变为
public:
static const AFX_DATA CRuntimeClass classCCmdTarget;
virtual CRuntimeClass *GetRuntimeClass() const;
即创建了一个静态CRuntimeClass成员变量
IMPLEMENT_DYNAMIC后变为
AFX_DATADEF CRuntimeClass CCmdTarget::classCCmdTarget={
"CCmdTarget",sizeof(CCmdTarget),0xFFFF,NULL,RUNTIME_CLASS(CObject),NULL};
static const AFX_CLASSINIT _init_CCmdTarget(&CCmdTarget::classCCmdTarget);
CRuntimeClass * CCmdTarget::GetRuntimeClass() const
{
//返回classCCmdTarget的地址
return &CCmdTarget::classCCmdTarget;
}
结合CRuntimeClass的定义得出:
CCmdTarget.m_pBaseClass=RUNTIME_CLASS(CObject)//即类CCmdTarget的父类指向CObject
AFX_CLASSINIT创建了一个静态的AFX_CLASSINIT接口,并调用了它的构造函数,参数是CCmdTarget::classCCmdTarget这一CRuntimeClass静态结构。使得CCmdTarget::classCCmdTarget被添加到MFC的一个内部状态链表中.
小结:先创建一个CRuntimeClass对象,然后在.c文件中初始化该对象,如对象的父类指针等,并且定义了方法GetRuntimeClass()的实现,以及将该类添加到MFC的一个CRuntimeClass链表中.
下一学习:动态创建