当前位置: 首页 > 图文教程 > 开发语言 > VC++ > FMD开发文集 -- MFC CObject浅析

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 FMD开发文集 -- MFC CObject浅析


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 87 ::
收藏到网摘: n/a

FMD开发文集 -- MFC CObject浅析
作者:冯明德

CObject是大部分的MFC类的基类 为了完成MFC类的判断、动态生成、序列化等特殊功能,CObject中添加了特定的处理。 为了进一步增强对MFC类对象的理解,在此对CObject源码及相关宏定义进行分析。 (所附代码并非原始代码,为说明问题而作了删减。) 主要介绍了以下几方面内容:

1.CObject简要声明
2.CRuntimeClass结构
3.RUNTIME_CLASS
4.DYNAMIC支持
5.DYNCREATE支持
6.SERIAL支持

一.CObject简要声明

class CObject{public:	virtual CRuntimeClass* GetRuntimeClass() const;	virtual ~CObject();	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) //调试模式用,多了nLine参数,用于保存原码行号。	void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);	void PASCAL operator delete(void *p, LPCSTR lpszFileName, int nLine);#endifprotected:	CObject();private:	CObject(const CObject& objectSrc);	void operator=(const CObject& objectSrc);// Attributespublic:	BOOL IsSerializable() const;	BOOL IsKindOf(const CRuntimeClass* pClass) const;// Overridables	virtual void Serialize(CArchive& ar);#if defined(_DEBUG) //调试模式下用	virtual void AssertValid() const;	virtual void Dump(CDumpContext& dc) const;#endifpublic:	static const AFX_DATA CRuntimeClass classCObject;	static CRuntimeClass* PASCAL _GetBaseClass();};
在此声明中很多都是纯虚函数,定义的一个一般对象的"界面"

二.CRuntimeClass结构

在CObject中包含一个静态成员变量
static CRuntimeClass classCObject;
它是MFC内部用来管理类的重要结构,记录了很多对象所属类的重要信息,通过它在运行时完成对类的管理。 很多内部管理成员函数及宏定义都建立在CRuntimeClass的基础上的。
struct CRuntimeClass{	//类名称	LPCSTR m_lpszClassName;	//大小	int m_nObjectSize;	//版本	UINT m_wSchema;	CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class	//指向基类CRuntimeClass的指针,用于在运行时记录类继承关系。#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};
三.RUNTIME_CLASS

RUNTIME_CLASS(class_name)用于返回指向运行时类信息结构的指针,定义如下:
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
四.DYNAMIC支持

在CObject 派生类中,可以获得动态"验证"支持,访问运行时类信息
方法:
声明时添加宏:DECLARE_DYNAMIC( class_name )
实现时添加宏: IMPLEMENT_DYNAMIC

原码分析:
DECLARE_DYNAMIC(class_name)相当于在类中添加如下声明 :
protected:	static CRuntimeClass* PASCAL _GetBaseClass(); public:	//静态成员CRuntimeClass,给此派生类添加了运行时类信息,	//这样就可以使用CRuntimeClass成员判断类信息了。	//此成员名字格式为"class"+"类名",RUNTIME_CLASS()宏就是返回此结构的指针	static const AFX_DATA CRuntimeClass class##class_name;	virtual CRuntimeClass* GetRuntimeClass() const;
IMPLEMENT_DYNAMIC:
#define IMPLEMENT_DY