MFC学习之 一 CObject和CRuntimeClass

一、CRuntimeClass


CObject和CRuntimeClass是MFC中两个非常重要的类/结 构,绝大部分MFC类都是以CObject做为基类, CRuntimeClass结构同CObject密不可分,了解它们对于深入理解MFC具有重要意义。 
struct CRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;       //存放ASCII类名的以空字符结尾的字符串
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)(); //应用程序是AFXDLL版本(链接动态库),则是一个指向函数的指针,该函数返回基类的CR//untimeClass结构。 
#else
CRuntimeClass* m_pBaseClass;
// 使用静态库时,定义一个指向基类的CRuntimeClass结构的指针
#endif
// Operations
CObject* CreateObject(); //从CObject派生的类可以支持动态创建,这是在运行时创建一个指定类的对象的能力。//CreateObject成员函数可以用来实现这个功能,在运行时为这些类创建对象
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;    //IsDerivedFrom类成员的类是从基类派生而来,该基类的CRuntimeClass结构作为一个参//数给出,则返回TRUE。
// 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
};
也就是说每新建一个类我们都可以加入MFC的继承表中,就是每个类声明中加入一个CRuntimeClass但是这个数据结构中有很多成员变量和函数。而且在实现文件中也要加入一些成员变量和函数的初始化或者成员函数的定义工作,每个类都要这么做会花很多行代码。还好微软给我们定义了几个宏让我们可以很方便的把我们定义的类加入到MFC继承的大绳中去。

1、DECLEAR_DYNAMIC(classname)//这个宏在声明文件中出现
#define DECLARE_DYNAMIC(class_name) \
public: \
static CRuntimeClass class##class_name; \              在类中建立一个CRuntimeClass的结构
virtual CRuntimeClass* GetRuntimeClass() const;        在类中建立一个虚拟函数
2.IMPLEMENT_DYNAMIC//这个宏出现在实现文件中
#define IMPLEMENT_DYNAMIC(class_name, base_class_name) \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, NULL)
而IMPLEMENT_RUNTIMECLASS宏的定义是
#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); } 
有了这个大网之后我们就可以判断一个类是不是另一个类的派生类.为了在得到一个类名后可以创建一个该类对象,我们不以直接NEW
出一个来,因为MFC不知道这是一个类,而CRUNTIMECLASS中可以加入一个构造函数,这样就可以支持动态创建一个已知类名的类的对象.
而MFC又提供给我们新的宏定义
在声明文件中需要DECLARE_DYNCREATE宏
#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \
static CObject* PASCAL CreateObject( );//往类中加入一个函数
在定义文件中需加入另一个宏
#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \
class_name::CreateObject)
二、CObject
CObject定义了一个CRuntimeClass类型的静态成员变量:
   CRuntimeClass classCObject 
  还定义了几组函数:   
构造函数析构函数类,诊断函数,与运行时类信息相关的函数,与串行化相关的函数。
  其中,一个静态函数:_GetBaseClass;五个虚拟函数:析构函数、GetRuntimeClass、Serialize、AssertValid、Dump。
这些虚拟函数,在CObject的派生类中应该有更具体的实现。必要的话,派生类实现它们时可能要求先调用基类的实现,
例如Serialize和Dump就要求这样。静态成员变量classCObject和相关函数实现了对CObject特性的支持。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值