原创 MFC的Serialize机制及其使用

2012-8-15 00:13 7246 21 22 分类: 软件与OS

http://gongziya.com/1043/mfc%E7%9A%84serialize%E6%9C%BA%E5%88%B6%E5%8F%8A%E5%85%B6%E4%BD%BF%E7%94%A8/

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

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

一个类要支持Serializable,必须遵循以下步骤:

  • 该类必须要继承自CObject
  • 在该类的头文件中添加DECLARE_SERIAL宏
  • 在该类的实现文件中添加 IMPLEMENT SERIAL宏
  • 为该类添加一个缺省构造函数
  • 在该类中重写Serialize( CArchive& ar )函数

之后,该类就可以被Serializable。

如何使用

譬如我们新建一个MFC应用程序,为了方便处理数据,我们在程序中单独创建自己的类MyClass:

1
2
3
4
5
6
7
8
9
10
MyClass:public CObject
{
DECLARE_SERIAL(MyClass)     //很重要一定要加上
 
public:
   virtual void Serialize(CArchive& ar);
public:
   int m_iVal;
   float m_fVal;
};

在实现文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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对象了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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加载机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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保存机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);

文章评论1条评论)

登录后参与讨论

用户377235 2015-7-23 10:05

头文件部分怎么填啊?照你这么写代码,编译还是出错啊

相关推荐阅读
mcuandme 2020-03-14 23:15
18位、线性、低噪声、精密双极性±10 V直流电压源
www.analog.com/zh/CN0200...
mcuandme 2020-03-14 21:51
C语言printf("")左对齐和右对齐 (转)
https://blog.csdn.net/abcdu1/article/details/74926375  原文地址1.左对齐方式1printf("%d\n",101010);默认打印格式...
mcuandme 2020-03-14 21:45
放大器电路设计中的常见问题经验总结
源地址:https://www.cnblogs.com/huanzxj/p/5667633.html与分立器件相比,现代集成运算放大器(op amp)和仪表放大器(in-amp)为设计工程师带来了许多...
mcuandme 2015-07-13 15:12
简单的固态继电器具有过零开关功能
本设计实例是一个固态继电器(SSR),它能利用双向晶闸管切换大电流的交流负载(图1)。市场上有大量简单的固态继电器电路,但这个电路可能是最简单的,它只在交流线路电压接近零时才导通和关断。 晶体管Q2...
mcuandme 2014-07-30 08:44
LIB和DLL的区别与使用
共有两种库: 一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。 ...
mcuandme 2013-12-19 22:16
Stellaris LM3S MCUs
今天买了个开发板 EKK LM3S3748 然后上网查资料是 Stellaris LM3S MCUs 系列的芯片 是CORTX M3 内核 但是TI官方网站已经推荐上级到  Upgrade...
我要评论
1
21
关闭 站长推荐上一条 /2 下一条