1 从 CObject 派生类
- 在 CObject 的讨论中,经常使用术语“接口文件”和“实现文件”。 接口文件(通常称为头文件,或 .H 文件)包含类声明和使用该类所需的任何其他信息。 实现文件(或 .CPP 文件)包含类定义以及实现类成员函数的代码
- 从 CObject 派生类时,可以从四个级别的功能中进行选择:
1)基本功能:不支持运行时类信息或序列化,但包括诊断内存管理
2)基本功能加上对运行时类信息的支持
3)基本功能加上对运行时类信息和动态创建的支持
4)基本功能加上对运行时类信息、动态创建和序列化的支持 - 为重用而设计的类(以后将用作基类的类)至少应包括运行时类支持和序列化支持(如果预期将来有任何序列化需求)
- 通过在从 CObject 派生的类的声明和实现中使用特定的声明和实现宏来选择功能级别
1.1 使用基本 CObject 功能
class CSimple : public CObject
{
};
1.2 添加运行时类信息
1.3 添加动态创建支持
- 从 CObject 类派生你的类
- 在类声明中使用 DECLARE_DYNCREATE 宏
- 定义没有参数的构造函数(默认构造函数)
- 在类实现文件中添加 IMPLEMENT_DYNCREATE 宏
1.4 添加序列化支持
- 从 CObject 类派生你的类
- 重写 Serialize 成员函数
如果直接调用 Serialize,即不希望通过多态指针序列化对象,请省略步骤 3 到 5 - 在类声明中使用 DECLARE_SERIAL 宏
- 定义没有参数的构造函数(默认构造函数)
- 在实现文件中使用 IMPLEMENT_SERIAL 宏
- “多态指针”指向类的对象(将其称为 A)或从 A 派生任何类的对象(例如 B)。 若要通过多态指针进行序列化,框架必须确定它正在序列化 (B) 的对象运行时类,因为它可能是从某些基类 (A) 派生的任何类的对象
2 访问运行时类信息
- 如果已从 CObject 派生类并使用了从 CObject 派生类一文中介绍的 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC、DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE、或 DECLARE_SERIAL 和 IMPLEMENT_SERIAL 宏,则 CObject 类能够在运行时确定对象的具体类
- 使用 RUNTIME_CLASS 宏
CRuntimeClass *pClass = RUNTIME_CLASS(CObject);
- 使用 IsKindOf 函数: 可用于确定某个特定对象是否属于某个指定类或者是否派生自某个特定类,且确保类具有运行时类支持
class CPerson : public CObject
{
DECLARE_DYNAMIC(CPerson)
};
3 动态对象创建
CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CMyClass);
CObject* pObject = pRuntimeClass->CreateObject();
ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CMyClass)));
- 在需要序列化或动态可创建性等功能时,可以从 CObject 派生一个类。 许多数据类需要序列化到文件中,因此,通常最好从 CObject 派生
- 从 CObject 类派生的开销是最小的。 派生的类仅继承四个虚函数和一个 CRuntimeClass 对象