eryar

PipeCAD - Plant Piping Design Software.
RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
posts - 603, comments - 590, trackbacks - 0, articles - 0

 

Writing Serializable Classes

定义可序列化的类

尽管MFCCFile类使文件的读写变得相当容易,但是通常MFC程序都不直接使用CFile对象。相反地,他们使用CArchive类来实现文件的读写,CArchive类最终还是通过CFile类来实现文件输入/输出。MFC得载了 <<>> 操作符来实现数据的进、出,主要是因为程序通常也是将数据存入或将数据取出。

SerializationMFC中一个重要概念,因为他是MFC在文档/视的程序中实现打开和保存文件的基础。

定义可序列化的类

一个对象若要支持可序列化,它必须是可序列化类的实例。定义一个可序列化的类分为以下五步:

  1. 使该类直接或间接继承类CObject
  2. 在类声明中包含MFC的宏DECLARE_SERIALDECLARE_SERIAL只要一个参数:类名;
  3. 重载基类的Serialize函数,并序列化继承类的成员数据;
  4. 若继承类没有默认构造函数,添加之。这步是必须的,因为当一个对象载入时,MFC使用默认构造函数创建一个对象,并用文件中的数据来初始化对象的成员函数;
  5. 在类的实现中包含MFC的宏IMPLEMENT_SERIAL。宏IMPLEMENT_SERIAL需要三个参数:类名、基类名和模式号(schema number)。模式号是一个整数,表示一个版本号。

实例

假设你定义了一个类CLine来表示直线,类有两个CPoint的成员变量来存储直线的端点,你想使这个类支持序列化。原始的类声明如下:

   1:  class CLine
   2:  {
   3:  protected:
   4:      CPoint m_ptFrom;
   5:      CPoint m_ptTo;
   6:   
   7:  public:
   8:      CLine (CPoint from, CPoint to) { m_ptFrom = from; m_ptTo = to; }
   9:  };

使该类支持序列化很容易,如下代码为添加序列化功能的类声明:

   1:  class CLine : public CObject
   2:  {
   3:  DECLARE_SERIAL (CLine)
   4:   
   5:  protected:
   6:      CPoint m_ptFrom;
   7:      CPoint m_ptTo;
   8:   
   9:  public:
  10:      CLine () {} // Required!
  11:      CLine (CPoint from, CPoint to) { m_ptFrom = from; m_ptTo = to; }
  12:      void Serialize (CArchive& ar);
  13:  };
  14:   

重载的序列化函数如下所示:

void CLine::Serialize (CArchive& ar)
{
    CObject::Serialize (ar);
    if (ar.IsStoring ())
        ar << m_ptFrom << m_ptTo;
    else // Loading, not storing
        ar >> m_ptFrom >> m_ptTo;
}
 

最后在类的实现文件中添加下面的宏即可:

   1:  IMPLEMENT_SERIAL (CLine, CObject, 1)

通过这些修改,这个类是完全支持可序列化的。


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理