Writing Serializable Classes
定义可序列化的类
尽管MFC的CFile类使文件的读写变得相当容易,但是通常MFC程序都不直接使用CFile对象。相反地,他们使用CArchive类来实现文件的读写,CArchive类最终还是通过CFile类来实现文件输入/输出。MFC得载了 << 和 >> 操作符来实现数据的进、出,主要是因为程序通常也是将数据存入或将数据取出。
Serialization是MFC中一个重要概念,因为他是MFC在文档/视的程序中实现打开和保存文件的基础。
定义可序列化的类
一个对象若要支持可序列化,它必须是可序列化类的实例。定义一个可序列化的类分为以下五步:
- 使该类直接或间接继承类CObject;
- 在类声明中包含MFC的宏DECLARE_SERIAL。DECLARE_SERIAL只要一个参数:类名;
- 重载基类的Serialize函数,并序列化继承类的成员数据;
- 若继承类没有默认构造函数,添加之。这步是必须的,因为当一个对象载入时,MFC使用默认构造函数创建一个对象,并用文件中的数据来初始化对象的成员函数;
- 在类的实现中包含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)
通过这些修改,这个类是完全支持可序列化的。