Serialization: Making a Serializable 类

需要五个主要步骤使类是可序列化的。 它们在以下各节下面列出并解释:

  1. 派生您的类从 CObject (或从 CObject派生的某些类)。

  2. 重写序列化成员函数。

  3. 在类声明的使用 DECLARE_SERIAL 宏 。

  4. 定义没有参数的构造函数。

  5. 您的类的使用实现文件中的 IMPLEMENT_SERIAL 宏 。

如果通过 CArchive的 >> 和 << 运算符直接调用 Serialize ,而不是前三个步骤对于序列化是必需的。

派生您的类从 CObject

基本序列化协议和函数。 CObject 类中定义。 通过派生您的类从 CObject (或从 CObject派生的类),如类中所示 CPerson的以下声明中,您将 CObject的序列化协议和功能的访问。

重写序列化成员函数

Serialize 成员函数,在 CObject 类中定义,对实际序列化所需的数据来获取对象的当前状态。 Serialize 函数具有它使用读取和写入对象数据的 CArchive 参数。 CArchive 对象的成员函数, IsStoring,指示是否 Serialize 存储区 (写入数据) 或加载 (读取数据)。 使用 IsStoring 的结果用作教程中,您的任何插入到对象的数据与插入运算符 (<<) 的 CArchive 对象或与提取运算符 (>>) 来提取数据。

考虑从派生 CObject 有两个新成员变量的类,类型 CStringWORD。 下面的类声明片段显示新成员变量和说明重写的 Serialize 成员函数:

class CPerson : public CObject
{
public:
    DECLARE_SERIAL( CPerson )
    // empty constructor is necessary
    CPerson();
   virtual ~CPerson();

    CString m_name;
    WORD   m_number;

    void Serialize( CArchive& archive );
};

重写序列化成员函数

  1. 调用您的 Serialize 的基类版本,以确保序列化对象的继承部分。

  2. 插入或提取成员变量特定于您的类。

    插入和提取运算符与存档类读取和写入数据。 下面的示例演示如何实现声明的 CPerson 类的 Serialize 上面:

    void CPerson::Serialize( CArchive& archive )
    {
        // call base class function first
        // base class is CObject in this case
        CObject::Serialize( archive );
    
        // now do the stuff for our specific class
        if( archive.IsStoring() )
            archive << m_name << m_number;
        else
            archive >> m_name >> m_number;
    }
    

还可以使用 CArchive::ReadCArchive::Write 成员函数读取和写入大量非类型化数据。

使用 DECLARE_SERIAL 宏

DECLARE_SERIAL 宏在支持序列化类的声明需要,如下所示:

class CPerson : public CObject
{
public:
    DECLARE_SERIAL( CPerson )

定义无参数的构造函数

MFC 需要默认构造函数,则重新创建您的对象时,它们被反序列化 (从磁盘加载)。 反序列化进程无需的值将填入所有成员变量重新创建对象。

此构造函数可以声明为公共,从而保护或保密。 如果要使其成为受保护或私有,有助于确保,它将由序列化功能只使用。 构造函数在允许如有必要,删除的状态必须置于对象。

备注

如果忘记定义构造函数不在使用 DECLARE_SERIALIMPLEMENT_SERIAL 宏的类的参数,则会在使用 IMPLEMENT_SERIAL 宏的行的 “没有默认构造函数可用”编译器警告。

使用实现文件中的 IMPLEMENT_SERIAL 宏

,当从 CObject时,可序列化派生类 IMPLEMENT_SERIAL 宏用于定义所需的各种功能。 在实现文件 (.CPP) 使用此宏对于您的类。 对宏的最后两个参数是类的名称及其直接基类的名称。

此宏的第三个参数是模式数字。 模式数字实质上是类的对象的版本号。 对模式数字使用整数值大于或等于 0。 (不要将此模式数字混淆数据库术语。)

,在读取对象到内存中时, MFC 序列化代码检查架构数字。 如果对象的架构数字在磁盘上不匹配类的模式数字内存中,库将引发 CArchiveException,以防止程序读取对象的不正确版本。

如果您希望 Serialize 成员函数可以读取多个版本也就是说,文件写入由应用程序的不同版本 —可以使用该值 VERSIONABLE_SCHEMA 作为参数传递给 IMPLEMENT_SERIAL 宏。 有关用法信息和示例,请参见类 CArchiveGetObjectSchema 成员函数。

下面的示例演示如何对该类使用 IMPLEMENT_SERIAL , CPerson,从 CObject派生:

IMPLEMENT_SERIAL( CPerson, CObject, 1 )

一旦具有可序列化类,您可以序列化类的对象,如这篇文章 序列化:序列化对象所述。

请参见

概念

在MFC的序列化