MFC 序列化对象,兼容以前的类对象版本

使用MFC序列化的步骤,带版本控制兼容之前的版本.

  1. 需要直接或间接从 CObject 派生类.
  2. 派生类中声明中声明支持序列化的宏 DECLARE_SERIALE
  3. 派生类重写基类的 Serialize 函数
  4. 派生类必须有一个无参数的默认构造函数
  5. 派生类实现支持序列化的宏 IMPLEMENT_SERIALE

示例代码

#pragma once
#include <afx.h>

// 声明要序列化的类, 必须直接或间接继承自CObject
class CCar : public CObject {
    // MFC 提供的宏,使当前类支持序列化机制
    DECLARE_SERIAL(CCar)

public:
    // 必须要有一个无参数的构造函数.
    CCar();

    // 重写基类的Serialize函数, 实现自己的序列化过程
    void Serialize(CArchive& ar);

public:
    CPoint m_Location;  // 汽车位置
    COLORREF m_Color;   // 汽车颜色
    int m_Speed;        // 汽车速度, 版本2新增的成员.
};
#include "pch.h"
#include "CCar.h"


// 与类声明中 DECLARE_SERIAL 宏的对应实现宏.
// 第三个参数:是类的版本号. 我们将在重写的Serialize函数中根据版本号来确定如何反序列化.
//      每当我们修改了类的数据结构后都要修改 版本号 和 序列化函数, 确保能够兼容之前的版本,不发生数据错误.
//      VERSIONABLE_SCHEMA 是一个固定的标志, 要使用版本控制就必须加上它.
IMPLEMENT_SERIAL(CCar, CObject, VERSIONABLE_SCHEMA | 2);

CCar::CCar() 
    : CObject(), m_Location({0}), m_Color(COLORREF(0)), m_Speed(0) {

}

void CCar::Serialize(CArchive& ar) {
    // 首先调用基类的序列化函数.
    CObject::Serialize(ar);

	// 实现自己的序列化和反序列化逻辑
    if (ar.IsStoring()) {
        // 版本1的序列化.
        //ar << m_Location << m_Color;  

        // 版本2的序列化.
        ar << m_Location << m_Color << m_Speed;
    }
    else {
        // 获取版本号.
        UINT nSchema = ar.GetObjectSchema();

        // 根据版本号来决定如何反序列化.
        switch (nSchema) {
        case 1:
            ar >> m_Location >> m_Color;
            m_Speed = 200;
            break;
        case 2:
            ar >> m_Location >> m_Color >> m_Speed;
            break;
        default:
            AfxThrowArchiveException(CArchiveException::badSchema);
        }
    }
}

void CMFCSerializeDlg::OnBnClickedButton1() {
    // 序列化一个CCar对象
    CCar car;
    car.m_Location = { 100,200 };
    car.m_Color = RGB(255, 0, 0);
    car.m_Speed = 100;

    CFile file(L"Car.data", CFile::modeCreate | CFile::modeWrite);
    CArchive ar(&file, CArchive::store);
    ar << &car;
    ar.Close();
}



void CMFCSerializeDlg::OnBnClickedButton2() {
    // 反序列化一个CCar对象
    CCar* car;
    CFile file(L"Car.data", CFile::modeRead);
    CArchive ar(&file, CArchive::load);
    ar >> car;

    TRACE(L"Location:%d,%d Color:%d Speed:%d\n", car->m_Location.x, car->m_Location.y, car->m_Color, car->m_Speed);
}
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值