1:串行化的基础
假定一个CFile对象,名为file,代表一个打开的文件。该文件具有写访问权,并且你想在文件上写一对整数,名为a和b。
(1)一种方法是对每一个整数都调用CFile::Write:
file.Write(&a,sizeof(a));
file.Write(&b,sizeof(b));
(2)另一种方法是创建一个CArchive对象,并把它与该CFile对象关联起来,然后运用<<运算符把整数串行化到档案中
CArchive ar(&file,CArchive::store);
ar<<a<<b;
CArchive对象也可以用来读取数据。假定file再次代表一个打开的文件,并且该文件具有读的访问权,下面的小代码段将CArchive对象挂接到文件上,并从文件中读取整数,或将整数“并行化”:
CArchive ar(&file,CArchive::load);
ar>>a>>b;
2:五个步骤编写可串行化的类:
(1)直接或间接得到CObject的派生类。
(2)在类的说明中写入MFC的DECLARE_SERIAL宏。DECLARE_SERIAL只接受一个参数:类名。
(3)重载基本类的Serialize函数,并串行化派生类的数据成员。
(4)如果派生类没有默认的构造函数(该函数没有参数),则添加一个。因为对象并行化时,MFC要用默认构造函数在浮动标签上创建对象,并用从档案取回的值设置对象数据成员的初始值。
(5)在类的实现中写入MFC的IMPLEMENT_SERIAL宏。IMPLEMENT_SERIAL宏接收三个参数:类名,基本类名和模式号。“模式号”是一个整型值,等于版本号。只要修改了类的串行化数据格式,模式号也要随之改变。
例:编写一个简单的类来代表线,名为CLine。该类有两个CPoint数据成员,它们存储着线的两个端点,并你想添加串行化支持。
最初,类的声明是这样
class CLine
{
protected:
CPoint m_ptFrom;
CPoint m_ptTo;
public:
CLine(CPoint from,CPoint to)
{
m_ptFrom=from;
m_ptTo=to;
}
}
下面使该类串行化,下面是添加串行化支持后的程序段
class CLine:public CObject
{
DECLARE_SERIAL(CLine)
protected:
CPoint m_ptFrom;
CPoint m_ptTo;
public:
CLine(){} //Required!
CLine(CPoint from, CPoint to)
{
m_ptFrom=from;
m_ptTo=to;
}
void Serialize(CArchive& ar);
};
//the Serialize function looks like this:
void CLine::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
if(ar.IsStoring())
ar<<m_ptFrom<<m_ptTo;
else
ar>>m_ptFrom>>m_ptTo;
}
该类实例被要求串行化或并行化时,MFC调用实例的CLine::Serialize函数。
在将自己的数据成员串行化之前,CLine::Serialize调用CCObject::Serialize串行化基本类的数据成员。
基本类调用返回之后,CLine::Serialize调用CArchive::IsStoring决定数据流方向。如果返回值为非0值,则数据串行化到档案中;如果是0,则数据被串行化读出。