MFC对可Serialize类型的版本控制

使用MFC提供的Serialize功能对类型进行序列化/反序列化非常的方便。当软件升级后,Serialize的内容可能也会发生变化,这时,就可以使用MFC提供的版本控制功能解决反序列化因为内容不同引起的冲突了。

编写可序列化类时,MFC用IMPLEMENT_SERIAL宏指定的模式号作为版本控制的依据。反序列化时,MFC将文件中记录的模式号与应用程序中使用的模式号进行对比,如果不匹配,MFC将抛出一个CArchiveException异常,其m_cause等于CArchiveException::badSchema。为了避免产生异常,我们需要在指定新模式号的同时使用VERSIONABLE_SCHEMA标志,如下所示:

IMPLEMENT_SERIAL(XX, XXX, 2 | VERSIONABLE_SCHEMA)    //假设升级前的模式号是1

这样,在Serialize函数内就可以通过GetObjectSchema函数获得反序列化文件的模式号了,如下所示:
void XX::Serialize(CArchive& ar)
{
    //Call base's Serialize method.

    if(ar.IsStoring())
    {
         //Save value to ar.
    }else
    {
         UINT ver = ar.GetObjectSchema();
         switch(ver)
         {
              case 1:
                    //Load old version value.
              break;
              case 2:
                   //Load new version value.
              break;
              default:
                   AfxThrowArchiveException(CArchiveException::badSchema);
              break;
         }
    }
}

注意:GetObjectSchema函数必须在读取对象数据之前调用,且只能调用一次,如果GetObjectSchema在调用Serialize前后被调用了两次,则返回-1。

 

可能有个别情况是模式号无法解决的,那时大家可以尝试这两个方法(摘自网络):
1. 对不同版本的序列化文件应该不同的扩展名,在Serialize中判断文件扩展名,调用相应的反序列化实现。
2. 制作版本升级工具,把旧版本的序列化文件转换为新版本格式。

你可能感兴趣的:(C/C++)