怎样给串行化类分配版本号(可配置版本模式)

2016-01-29 12:26 12 1 收藏

怎样给串行化类分配版本号(可配置版本模式),怎样给串行化类分配版本号(可配置版本模式)

【 tulaoshi.com - C语言心得技巧 】

怎样给串行化类分配版本号(可配置版本模式)

作者:阿豪(kof)

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com) 下载源代码

  编写可串行化类时,MFC用你指定的模式号制定一个粗略的版本控制方式。在向档案写数据时,MFC用模式标记该类的实例;而在读回数据时,MFC将档案中的记录的模式号和应用程序中使用着的该类对象的模式号做比较,如果两模式号不匹配,则MFC发送一个CArchiveException,其m_cause等于CArchiveException::badSchema。没有得到处理的该类异常会促使MFC显示一个对话框,提示“非预期的文件格式”。如果每次修改对象的串行化存储格式时都能做到增加模式号,那么就不怕这种无心的操作—试图把磁盘中存的老版本对象读入内存里的新版本对象了。
  有一个问题经常会突然在使用可串行化类的应用程序中出现,这就是向下兼容。换句话说,就是如何并行化在老版本应用程序中创建的对象。如果对象的持久存储格式随应用程序版本的更新发生了变化,这时你可能希望新版本应用程序对两种格式都能读。但是一旦MFC发现不配套的模式号,它就发送异常。鉴于MFC的结构特点,最好按照MFC的方式处理异常并终止串行化过程。 可视化模式也就产生了。
  可视化模式只是包含VERSIONABLE_SCHEMA标志的模式号。标志告诉MFC应用程序针对某一类能够处理多种串行化的数据格式。这种模式禁止CArchiveException,并允许应用程序对不同的模式号有判断地响应。使用了可视化模式的应用程序可以提供用户希望的向下兼容性。 如果要编写一个具有MFC可视化模式支持的可串行类,一般需要两步: 将IMPLEMENT_SERLAL宏中的模式号与值VERSIONABLE_SCHEMA相或。 如果从档案加载对象时需要调用CArchive::GetObjectSchema,则要修改类的Serialize函数,并相应地调整其并行化例程。GetObjectSchema返回要进行并行化对象的模式号。

  调用GetObjectSchema时要注意几个规则。首先,只有对象在被并行化时才能调用。其次,必须在读取档案对象数据之前调用。再者,它只能调用一次。如果GetObjectSchema在调用Serialize前后调用两次,则返回-1。我们先看个例子,这是版本1的CLine类:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)
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);};
这是Serialize函数:
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;}
在实现类的过程中出现的语句:
IMPLEMENT_SERIAL (CLine, CObject, 1)
  这个类就可以串行化了。目前版本号为1,如果后来又给CLine添加了一个持久性数据成员,则要把版本号增加到2,这样主结构就能根据程序的不同版本区别串行化到磁盘的CLine对象了。否则,磁盘上的版本为1的CLine就可能被读入内存中版本为2的CLine,从而可能造成严重后果。
  假定在应用程序的第2版本中,你要修改CLine类,想添加一个成员变量,用来保存线的颜色。下面是修改后的类的声明:
class CLine : public CObject{DECLARE_SERIAL (CLine)protected:    CPoint m_ptFrom;    CPoint m_ptTo;    COLORREF m_clrLine; // Line color (new in version 2)public:    CLine () {}    CLine (CPoint from, CPoint to, COLORREF color)        { m_ptFrom = from; m_ptTo = to; m_clrLine = color }    void Serialize (CArchive& ar);};
  因为线的颜色是持久属性(也就是说,保存到档案中的红线在读出时依旧是红的。),所以你向修改CLine::Serialize,使它在串行化m_ptFrom和m_ptTo之外还能串行化m_clrLine。这意味着要把CLine的模式号增加到2。使用原类时按以下方式调用MFC的IMPLEMENT_SERIAL宏:
IMPLEMENT_SERIAL(CLine,CObject,1)
但是在修改后的类中,应该这样调用IMPLEMENT_SERIAL:
IMPLEMENT_SERIAL(CLine,CObject,2|VERSIONABLE_SCHEMA)
  更新后的程序在读取CLine对象时,如果对象的模式号是1,MFC也不会发送CArchive异常,因为模式号中有VERSIONABLE_SCHEMA标志。但是它会了解到:由于模式号从1变为2,两个模式实际上是不同的。
  现在工作只做到一半。最后一步是修改CLine::Serialize,使它根据GetObjectSchema不同的返回值并行化CLine。原Serialize函数如下:
void CLine::Serialize (CArchive& ar){    CObject::Serialize (ar);    if (ar.IsStoring ())        ar << m_ptFrom << m_ptTo;    else // Loading, not storing
                        

来源:https://www.tulaoshi.com/n/20160129/1486087.html

延伸阅读
标签: windows系统
win8.1怎么查看系统版本号?   第一种方法 通过右键点击开始菜单打开系统选项在打开的窗口中可以查看系统信息。 第二种方法 打开超级菜单中的设置,点击右下角更改电脑设置; 然后再点击电脑和设备; 点击后再点击电脑信息即可。 Win8.1无法激活怎么办? &nbs(www.tulaoshi.com)p; ...
标签: windows10
win10怎么看版本号   进入WIN10系统以后,在左下角处的开始图标上面点击右键,然后在出来的工具中点击或者是按快捷键调出运行工具。 在运行工具这里输入再点击 在出来的DirectX诊断工具下面找到操作系统,那个操作系统最后面就有一个版本。这个版本就是想要的那个版本号。 win10搜索栏怎样去掉   Wi...
标签: 电脑入门
win10版本号怎么看呢?想不想知道win10版本号是多少呢?下文图老师小编就为大家带来win10版本号查看方法,一起去看看具体内容吧。 进入WIN10系统以后,在左下角处的开始图标上面点击右键,然后在出来的工具中点击或者是按快捷键调出运行工具。 在运行工具这里输入再点击. 在出来的DirectX诊断工具下面找到操作系统,那个操作系统最后面就有...
标签: PHP
  再用用程序时,一般需要对php版本号整数化后进行判断,从而确定输出。 <?php $temp=explode(".",phpversion()); //以数组形式获取版本号 $num=count($temp);               //计算数组中的元素数量 $phpver=0; switch($num) {  ...
《真人快打X》版本号识别方法解析攻略 最近看到有玩家说,不知道怎么看《真人快打X》的版本号,今天图老师图老师小编给大家带来了《真人快打X》版本号识别方法解析攻略!不知道怎么看版本号的玩家快来看看吧! 方法一: 按照以下顺序 主菜单-设置-GAMEPLAY 进一下后右下角就有版本号了。 方法二: 这个是最新的4号升级:22254.1。 你们看...

经验教程

165

收藏

90
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部