MFC的Serialize机制及其使用

一、CArchive类介绍

https://blog.csdn.net/weixin_45525272/article/details/106481559

二、序列化(Serialization)

MFC提供了非常方便的串行化函数Serialize()。利用这个机制可以很方便的对文档进行存取和读取。

1、 序列化提出和定义

序列化在面向对象的程序设计中出现的,它基于对象是可以连续的思想,在程序退出或者启动的时候,可以把对象顺序的存储在磁盘或者从磁盘读出,存储和读出对象的过程叫做序列化。

2、 序列化存储的应用和局限

序列化存储可以把对象存储到磁盘上,但它并不能代替数据库设计的信息存储,因为它只是顺序的存取,没有检索机制。

3、 序列化的类

序列化的类可以直接或者间接从CObject类派生,类的声明中必须包含DECLARE_SERIAL 宏调用,实现文件也必须有与之对应的宏:
IMPLEMENT_SERIAL。(注意: DECLARE_SERIAL/IMPLEMENT_SERIAL包含了DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏)。

4、 MFC中序列化的使用

如果应用程序没有进行直接磁盘操作的输入输出,而是依靠序列化的过程,那么就不必直接使用CFile对象。MFC库中文档类的Serialize函数和CFile对象之间有一个CArchive对象。该对象为CFile对象缓冲数据并保持一个内部标志,来指明是存储或者加载对象。MFC应用程序框架负责CFile和Carchive对象构造及关联。在自动生成的菜单File Open 和FileSave等过程中,应用程序框架会调用文档的Serialize函数,我们可以在该函数中处理特定类对象的序列化。

Serialization就是面向对象世界里面的永久生存机制,对象必须能够永久生存,也就是他们必须能够在程序结束时存储到文件当中,并且能够在程序重新激活时在恢复过来,存储和恢复对象的过程在MFC称之为Serialization,负责这项重要任务的是MFC Object类中的一个名为Serialize()的虚函数,文件的读写操作均通过它来方便的完成。

5、遵循步骤

一个类要支持Serializable,必须遵循以下步骤:
该类必须要继承自CObject
在该类的头文件中添加DECLARE_SERIAL宏
在该类的实现文件中添加 IMPLEMENT SERIAL宏
为该类添加一个缺省构造函数
在该类中重写Serialize( CArchive& ar )函数
之后,该类就可以被Serializable。
如何使用:
譬如我们新建一个MFC应用程序,为了方便处理数据,我们在程序中单独创建自己的类MyClass:

MyClass:public CObject
{
DECLARE_SERIAL(MyClass)     //很重要一定要加上
public:

   virtual void Serialize(CArchive& ar);

public:
   int m_iVal;
   float m_fVal;

};

在实现文件中:


IMPLEMENT_SERIAL(MyClass,CObject,1)

void MyClass::Serialize(CArchive& ar)
{
   if(ar.IsLoading())
   {
      //从文件中读取数据到内存中
      ar >> m_iVal;
      ar >> m_fVal;

   }
   else if(ar.IsStoring())
   {
      ar << m_iVal;
      ar << m_fVal;
   }
}

然后在MFC程序的C**Doc类中添加一个MyClass类型的对象myclass:

class C***Doc : public CDocument
{
public:
  C***Doc();
  DECLARE_DYNCREATE(C***Doc)
public:
  MyClass myclass;

public:
 	virtual void Serialize(CArchive& ar);
*******

}

并且在C***Doc类的Serialize()函数中调用我们的myclass对象的Serialize函数就可以永久保存myclass对象了:

IMPLEMENT_DYNCREATE(C***Doc, CDocument)
BEGIN_MESSAGE_MAP(C***Doc, CDocument)
END_MESSAGE_MAP()

IMPLEMENT_SERIAL(MyClass,CObject,1);
void C***Doc::Serialize(CArchive& ar)
{
 if (ar.IsStoring())
 {
   myclass.Serialize(ar);
 }
 else
 {
   myclass.Serialize(ar);
 }

}

如何触发Serialize

当我们新建一个基于文档的MFC程序时,向导会自动为我们创建一些菜单,点击菜单的保存或者打开文件按钮时,内部机制自动触发Serialize函数调用,那么怎样在程序中自己触发Serialize呢?

剖开文件保存和打开内部机制(详见深入浅出MFC),对于读取文件,会得到类似这样的调用来触发Serialize加载机制:

CFileException fe;

CFile *pFile=GetFile("d://file.txt",

              CFile::modeRead | CFile::shareDenyWrite,

              &fe);

DeleteContents();

SetModifiedFlag();

CArchive loadArchive(pFile,CArchive::load );

loadArchive.m_pDocument=this;

loadArchive.m_bForceFlat=FALSE;

CWaitCursor wait;

if(pFile->GetLength()!=0)

   Serialize(loadArchive);

loadArchive.Close();

ReleaseFile(pFile,FALSE);

类似的,可以使用下面的操作来触发Serialize保存机制:

CFileException fe;

CFile *pFile=GetFile("d://file.txt",CFile::modeCreate|

         CFile::modeWrite | CFile::shareDenyWrite,

         &fe);

DeleteContents();

SetModifiedFlag();

CArchive saveArchive(pFile,CArchive::store );

saveArchive.m_pDocument=this;

saveArchive.m_bForceFlat=FALSE;

CWaitCursor wait;

if(pFile->GetLength()!=0)

Serialize(saveArchive);

saveArchive.Close();

ReleaseFile(pFile,FALSE);

猜你喜欢

转载自blog.csdn.net/weixin_45525272/article/details/106593447