首页 > 其他分享 >在MFC中使用CArchive进行串行化数据

在MFC中使用CArchive进行串行化数据

时间:2024-01-05 21:56:09浏览次数:32  
标签:CFile MFC CArchive ar CObject MyDoc 串行化

使用CArchive进行数据串行化非常的方便。

CArchive持有一个CFile对象,通过此对象进行读写,那么所有基于CFile的子类,都可以使用CArchive来进行串行化。

示例:

CFile file(_T("1.txt"), CFile::modeReadWrite);
CArchive ar(&file, CArchive::load);

此时CArchive对象就是处于读取的状态,我们可以直接通过ar >> obj进行读取。

这里有一个要求,就是obj的类型必须是已经实现的operator >> 重载的类型。像CString,int,double这种,CArchive都已经实现了,可以直接使用。

这里有一个注意就是CArchive在串行化的时候,会向输出中添加以下其他信息,用来识别数据的类型,版本等。

那么来看一下如何让自定义的类型支持串行化,自定义的类型实现串行化,这里主要依靠operator >> 重载的CObject*的串行化版本。那么所有基于CObject的子类都可以实现串行化。

class MyDoc :
    public CObject
{
    DECLARE_SERIAL(MyDoc);
public:
    MyDoc() = default;
    MyDoc(int i, CString str);


    int m_i = 0;
    CString m_str = _T("");
public:
    virtual void Serialize(CArchive& ar);
};

这里主要是有三点是必须要做的:

1、继承CObject

2、实现宏 DECLARE_SERIAL(MyDoc);

3、重现CObject的虚函数 virtual void Serialize(CArchive& ar);

4、编写默认构造函数。

#include "MyDoc.h"

IMPLEMENT_SERIAL(MyDoc, CObject, 1 | VERSIONABLE_SCHEMA);

MyDoc::MyDoc(int i, CString str):m_i(i),m_str(str)
{
}


void MyDoc::Serialize(CArchive& ar)
{
    CObject::Serialize(ar);
    if (ar.IsStoring())
    {    
        // storing code
        ar << m_i << m_str;
    }
    else
    {    
        // loading code
        UINT schema = ar.GetObjectSchema();
        switch (schema)
        {
        case 1:
            ar >> m_i >> m_str;
            break;
        default:
            AfxThrowArchiveException(CArchiveException::badSchema);
            break;
        }
    }
}

首先看一下, IMPLEMENT_SERIAL(MyDoc, CObject, 1 | VERSIONABLE_SCHEMA); 这句话的意思,

此宏是DECLARE_SERIAL(MyDoc);的定义实现,通过前两个参数实现MyDoc与CObject的链接,后面1是版本号,宏VERSIONABLE_SCHEMA表示版本号是可变的。

版本号是什么意思呢,就是说如果我们的MyDoc对象在后期增加了数据成员,由于之前串行化的数据没有这个成员,那么版本号就起作用了,我们可以读取文件的版本号,来选择如何反序列化对象。如果老版本的串行化没有后期增加的数据成员,这里只需要反序列化已经有的数据,没有的做单独的初始化即可。

看一下虚函数的实现:

虚函数的实现首先串行化基类CObect对象,然后再串行化自身,这是常规的方式。

对于要序列化的MyDoc对象,这里可以直接使用CArchive对象进行串行化写入,那么在读取时,需要先获取文件的版本号,根据版本号进行操作。

下面是具体的使用例子:将MyDoc对象串行化。

try
{
    CFile file(_T("1.txt"), CFile::modeReadWrite);
    CArchive ar(&file, CArchive::store);
    MyDoc* doc = new MyDoc(666,_T("hello,word!"));
    ar << doc;
    ar.Flush();
    delete doc;

}
catch (CArchiveException* e)
{
    e->ReportError();
    e->Delete();
}

然后将对象反序列化:

try
{
    CFile file(_T("1.txt"), CFile::modeReadWrite);
    CArchive ar(&file, CArchive::load);
    MyDoc* doc = new MyDoc;
    ar >> doc;
    // 处理doc
    //。。。。。。。。。。。

    delete doc;

}
catch (CArchiveException* e)
{
    e->ReportError();
    e->Delete();
}

CArchive在串行化基于CObject的子类时,要注意,一定是指针,在反序列化时,对象必须时基于堆上的内存指针。

 

标签:CFile,MFC,CArchive,ar,CObject,MyDoc,串行化
From: https://www.cnblogs.com/Super-biscuits/p/17948177

相关文章

  • 实现MFC中CListCtrl双击单元格获取文本
    1.在类中定义CEdit控件CEdit*m_edit;2.窗口OnInitDialog创建窗口并设置父窗口为CListCtrl,设置字体m_edit=newCEdit();m_edit->Create(ES_LEFT|WS_CHILD|WS_TABSTOP|WS_BORDER,CRect(10,10,100,100),&m_lstRecord,1);m_edit->SetFont(......
  • MFC---路径格式化
    在路径字符串格式化时,通常需要使用双反斜杠\而不是单斜杠//。在文件路径中,Windows系统通常使用反斜杠\作为路径分隔符。问题出现问题原因问题解决......
  • mfc中tabsheet
    //TabSheet.cpp:implementationfile//#include"stdafx.h"#include"pch.h"//#include"Property5.h"#include"TabSheet.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;......
  • MFC CStatic 里面加载图片
    ▲效果头文件新增空间指针:private:CStatic*pBMP;BOOLCMFCApplicationBMPDlg::OnInitDialog()里面初始化://TODO:在此添加额外的初始化代码//初始化字段pBMP=(CStatic*)GetDlgItem(IDC_STATIC_BMP);//除了添加控件,还有这种方式获得控件的方式。pBMP->ModifyStyl......
  • MFC CListVtrl 控件简单测试
    ▲样式Demo关联控件变量m_CList,在属性中将视图(View)设置成Report(报表)模式。在BOOLCMFCApplication4LlisBoxDlg::OnInitDialog()初始化函数中添加测试代码://TODO:在此添加额外的初始化代码//m_CList.SetView(1);//视图View要改成Report报表模式//设置风格样式//......
  • 无涯教程-MFC - List Control函数
    列表视图控件的功能,该控件显示项目的集合,每个项目由一个图标和一个标签组成,它由CListCtrl类表示,列表控件包括使用以下视图显示项目列表。IconsSmallIconsListReport让无涯教程通过创建一个新的基于MFC对话框的应用程序来研究一个简单的示例。步骤1-删除TODO行并拖动一......
  • 无涯教程-MFC - Tree Control函数
    TreeViewControl是一个窗口,其中显示项目的层次结构列表,例如文档中的标题,索引中的条目或磁盘上的文件和目录,每个项目都包含一个标签和一个可选的位图图像,并且每个项目都可以具有与其相关联的子项目列表,通过单击一个项目,用户可以展开和折叠子项目的关联列表,它由CTreeCtrl类表......
  • 无涯教程-MFC - Date & Time Picker函数
    日期和时间选择控件(CDateTimeCtrl)实现了一种直观且可识别的输入或选择特定日期的方法,选择日期后,月份日历控件将自动消失。让无涯教程通过创建一个新的MFC应用程序来研究一个简单的示例。步骤1-删除标题并将其ID设置为IDC_STATIC_TXT。步骤2-为文本控件添加value变量。......
  • 无涯教程-MFC - Timer函数
    MFC计时器既没有按钮来表示它,也没有类,要创建计时器,只需调用CWnd::SetTimer()方法,此函数调用为您的应用程序创建一个计时器,像其他控件一样,计时器使用标识符。让无涯教程创建一个新的基于MFC对话框的应用程序。步骤1-删除标题并将其ID设置为IDC_STATIC_TXT步骤2-为文本控件......
  • 无涯教程-MFC - Checkboxes函数
    复选框是Windows控件,允许用户将项目的值设置或更改为true或false。让无涯教程创建一个新的基于MFC对话框的项目。创建项目后,您将在设计器窗口中看到以下对话框。步骤1-删除TODO行,并拖动一个复选框和一个Edit控件,如以下快照所示。还将复选框的标题更改为"EnableControl"。......