MFC CObject简析

本文详细介绍了MFC框架中的三个核心特性:运行时类信息、动态创建及对象序列化。通过对CObject类的深入剖析,揭示了这些特性的实现原理及应用方式。
//VS2008代码如下
class AFX_NOVTABLE CObject
{
public:

// Object model (types, destruction, allocation)
	virtual CRuntimeClass* GetRuntimeClass() const;
	virtual ~CObject() = 0;  // virtual destructors are necessary

	// Diagnostic allocations
	void* PASCAL operator new(size_t nSize);
	void* PASCAL operator new(size_t, void* p);
	void PASCAL operator delete(void* p);
#if _MSC_VER >= 1200
	void PASCAL operator delete(void* p, void* pPlace);
#endif

#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
	// for file name/line number tracking using DEBUG_NEW
	void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
#if _MSC_VER >= 1200
	void PASCAL operator delete(void *p, LPCSTR lpszFileName, int nLine);
#endif
#endif

	// Disable the copy constructor and assignment by default so you will get
	//   compiler errors instead of unexpected behaviour if you pass objects
	//   by value or assign objects.
protected:
	CObject();
private:
	CObject(const CObject& objectSrc);              // no implementation
	void operator=(const CObject& objectSrc);       // no implementation

// Attributes
public:
	BOOL IsSerializable() const;
	BOOL IsKindOf(const CRuntimeClass* pClass) const;

// Overridables
	virtual void Serialize(CArchive& ar);

#if defined(_DEBUG) || defined(_AFXDLL)
	// Diagnostic Support
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

// Implementation
public:
	static const CRuntimeClass classCObject;
#ifdef _AFXDLL
	static CRuntimeClass* PASCAL _GetBaseClass();
	static CRuntimeClass* PASCAL GetThisClass();
#endif
};
说明:
_MSC_VER 定义编译器的版本。下面是一些编译器版本的_MSC_VER值:
MS VC++ 12.0 _MSC_VER = 1800 (Visual C++ 2013)
MS VC++ 11.0 _MSC_VER = 1700 (Visual C++ 2012)
MS VC++ 10.0 _MSC_VER = 1600(Visual C++ 2010)
MS VC++ 9.0 _MSC_VER = 1500
MS VC++ 8.0 _MSC_VER = 1400
MS VC++ 7.1 _MSC_VER = 1310
MS VC++ 7.0 _MSC_VER = 1300
MS VC++ 6.0 _MSC_VER = 1200
MS VC++ 5.0 _MSC_VER = 1100


一、运行时类信息

BOOL IsKindOf(const CRuntimeClass* pClass) const;



        该特性用于在运行时确定一个对象是否属于一特定类(是该类的实例),或者从一个特定类派生来的。CObject 提供IsKindOf 函数来实现这个功能。(即在程序代码中可以通过 xxObject.IsKindOf(RUNTIME_CLASS(XXClass))来判断xxObject对象是否是属于XXClass类,或者xxObject是否是从XXClass类派生而来)。


在编写类时候,一定要添加如下东西

        定义该类时,在类说明中使用DECLARE_DYNAMIC(CLASSNMAE)宏;

        在类的实现文件中使用IMPLEMENT_DYNAMIC(CLASSNAME,BASECLASS)宏。


二、动态创建

    就是在运行时由MFC动态创建我们自己指定的类的实例。如:框架窗口对象、视对象,还有文档对象都需要由文档模板类(CDocTemplate)对象来动态的创建。它们并不是当我们需要框架的时候就亲手写上CFrameWnd myFrame;需要视的时候就自己写上CView myView的代码。而是定义该类时,在类说明中我们通过DECLARE_DYNCREATE(CLASSNMAE)宏来告诉MFC框架我们希望它为我们动态创建的类的类名。同时提供一个不带参数的构造函数。再在在类的实现文件中使用IMPLEMENT_DYNCREATE ( CLASSNAME ,BASECLASS)。如此,MFC框架就可以为我们动态创建该类对象了。


三、对象序列化
    “序列化”就是把对象内容存入一个文件或从一个文件中读取对象内容的过程。即是把一个对象的各种相关数据按照某种规则将它们从内存中拿出来存入到临时或永久性存储区中(如文件形式)。而反序列化就是再按照某种规则根据序列化的内容再重新为它分配内存,在内存中把对象状态还原出来的过程。
    定义该类时,在类说明中使用DECLARE_SERIAL(CLASSNMAE)宏;
    定义一个不带参数的构造函数(默认构造函数);
    在类的实现文件中使用IMPLEMENT_SERIAL(CLASSNAME,BASECLASS)宏;
    覆盖Serialize 成员函数。(如果直接调用Serialize 函数进行序列化读写,可以省略前面三步。)

注:要实现这三种特性,都必须以从CObject类继承为基础,然后再是那一系列的宏。此外,对运行时类信息的支持、动态创建的支持、串行化的支持层(不包括直接调用Serailize实现序列化),这三种功能的层次依次升高。如果对后面的功能支持,必定对前面的功能支持。支持动态创建的话,必定支持运行时类信息;支持序列化,必定支持前面的两个功能,因为它们的声明和实现都是后者包含前者。
### MFC 中 `CObject` 类的关系和用法 #### CObject 的角色与功能 `CObject` 是 Microsoft Foundation Classes (MFC) 库中的基础类之一,几乎所有的 MFC 类都直接或间接地继承自这个类。此设计使得整个库具有统一的对象模型[^1]。 #### 继承结构 许多重要的 MFC 类都是从 `CObject` 派生出来的,其中包括但不限于: - `CCmdTarget`: 提供命令路由和支持 OLE 自动化的功能。 - `CFile`: 实现文件 I/O 功能。 - 文档模板 (`CDocTemplate`) 和文档管理器 (`CMDIFrameWnd`, `CFrameWnd`) 对于具体的派生链路,在某些情况下可能涉及多层继承。例如,`CView` 又是从 `CCmdTarget` 进一步派生而来的,用于处理窗口消息并提供绘图支持;同样地,各种控件类也大多最终追溯到 `CObject` 作为其祖先[^2]。 #### 使用方法 为了利用好 `CObject` 所提供的特性,开发者可以遵循如下实践: - **动态内存分配**: 当创建对象实例时,默认构造函数会调用内部机制来初始化必要的资源。如果子类需要额外的初始化工作,则应在自己的构造函数中显式调用父类版本。 - **序列化支持**: 如果希望实现持久化存储(即保存至磁盘再读取),那么应该覆盖虚函数 `Serialize()` 方法,并在此处定义如何写入/读取成员变量的数据流形式。这允许应用程序轻松地存档复杂的数据结构而不必担心底层细节。 - **诊断输出**: 调试期间可以通过覆写 `Dump()` 函数来自定义调试信息打印逻辑,这对于排查问题非常有用。 ```cpp class MyCustomClass : public CObject { public: // 构造函数 MyCustomClass() {} protected: DECLARE_DYNAMIC(MyCustomClass) virtual void Serialize(CArchive& ar); }; IMPLEMENT_DYNAMIC(MyCustomClass, CObject) void MyCustomClass::Serialize(CArchive& ar){ if(ar.IsStoring()){ // 存储过程... }else{ // 加载过程... } } ``` 上述代码片段展示了怎样基于 `CObject` 创建一个新的可序列化类,并实现了基本的序列化接口以便于后续操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值