精华内容
下载资源
问答
  • MFC Serialize

    2015-05-09 14:06:58
    文档数据保存到文件或从文件中读取数据,都是通过序列化函数Serializ()实现的。...1.函数Serialize()的原理  该函数的应用形式如下: void CMyTestDoc::Serialize(CArchive& ar){ if(ar.Is

    转自http://www.360doc.com/content/10/0722/10/1066008_40609648.shtml


    文档数据保存到文件或从文件中读取数据,都是通过序列化函数Serializ()实现的。
    1.函数Serialize()的原理
     该函数的应用形式如下:
    void CMyTestDoc::Serialize(CArchive& ar){
    if(ar.IsStoring()){
    ar<<m_Name<<m_Num;
    }
    else{
    ar>>m_Name>>_Num;
    }
    }
    函数Serialize()的参数ar是档案类CArchive的对象的引用,其包含一个CFile类型的文件指针。CArchive对象为读写
    CFile对象中的可串行化数据提供了类型安全缓冲机制。CArchive对象只能读数据或写数据,而不能同时读写数据。当保存数据到对象ar时,该对象先将数据放至缓冲区中,直到缓冲区满,该对象才将数据写入文件指针指向的CFile对象中。当从对象ar读数据时,该对象从文件中读取内容到缓冲区,然后再从缓冲区读入到可串行化的对象中。该安全缓冲机制先集中在缓冲区中操作,减少了访问磁盘的次数,提高了不起应用程序的性能。
      ar保存了打开文件的信息以及读或写等信息。当向文件中写数据时,执行ar.IsStoring(),操作符"<<"把数据存到ar定制的文件。当从文件读数据时,操作符">>"从文件中读出数据,并初始化相关成员变量。
    (ar是由应用程序框架完成初始化的.)
    2.函数Serialize()的调用
    当读取文件或保存文件时,都要发生文档对象的序列化操作,即调用函数Serialize().
    (1)读取操作
    <1>单击应用程序菜单“File|New”,应用程序调用函数OnNewDocument()建立新文档。OnNewDocument()调用虚函数DeleteContents()清空文档类数据成员,然后再调用SetModifiedFlag(FALSE)将文档修改标志清除。
    <2>单击应用程序菜单"File|Open",应用程序调用函数OnOpenDocument()打开已有文档。函数OnOpenDocument()调用GetFile()获取给定文件的CFile指针,再调用DeleteContents()函数清空文档类数据成员,然后把CFile指针构造CArchive对象交给Serialize函数完成读文件重建文档对象的工作,再调用SetModifiedFlag(FALSE)将文档修改标志清除。其执行流程如图:

     

    (2)保存操作。
     单击应用程序菜单“File|Save”或者“File|Save As”时,应用程序调用函数OnSaveDocument()保存指定指定文件名的文档。函数OnSaveDocument()询问文件名,调用函数GetFile()获得给文件的CFile指针,再调用函数DeleteContents()清空文档类数据成员,接着把CFile指针构造CArchive对象交给Serialize函数完成读文件重建文档对象的工作,最后调用SetModifiedFlag(FALSE)将文档修改标志清除。其执行流程如图:


    (3)可序列化的数据类型
    (4)可序列化函数的局限性
    一般情况下,序列化函数可以完成文档数据的序列化操作,但是该函数也存在一定的局限性。
    <1>序列化函数Serialize()只能顺序读写文件,而不能随机操作。并且该函数只能一次性读写全部文件,而不能读取文件的部分内容。针对该限制,开发人员可以通过获取CFile指针,再调用CFile::Open(),CFile::Read(),CFile::Write()等函数,来支持随机或部分读写文件。
    <2>序列化函数Serialize只能操作二进制文件,不能处理文本文件,即利用该函数保存的文件不能像文本文件那样个具有可读性。类CSdioFile可产生可读性文件,在应用程序框架中可利用类CStdioFile解决二进制文件不可读问题。
    <3>序列化函数Serialize()不支持数据文件操作,也不能共享操作文件。开发人员可以通过重载虚函数OnOpenDocument(),OnNewDocument()和OnSaveDocument(), 并在这些虚函数内按数据库访问接口编写读写数据代码来访问数据库文件,而把对数据库的操作和并发控制等任务交给数据库管理系统处理。
    (4)自定义可序列化类
    某类只有派生自CObject且重定义了Serialize()函数才能实现序列化,MFC定义了两个宏支持序列化,它们是DECLARE_SERIAL和IMPLEMENT_SERIAL.自定义一个可序列化类的具体步骤如下:
    <1>将类的基类定义为CObject或其派生类
    自定义的派生于CObject的类,可以访问CObject类的基本序列化协议和功能。其代码如下:
    class CStudent::public CObject{
    public:
    CStudent();
    virtual ~CStudent();
    };
    <2>覆盖该类的Serialize成员函数
    序列化函数被定义在类CObject中,其操作序列化描述对象当前状态所必需的数据。成员函数Serialize的参数是一个CArchive对象的引用,用来读写对象数据。
    CArchive对象的成员函数IsStoring()用来表示序列化是存储还是读取。其具体代码如下:
    类CStudent
    //Student.h
    class CStudent:public CObject{
    public:
    CString m_Name;
    int m_Num;
    ...
    void Serialize(CArchive& ar);
    };
    //Student.cpp
    void CStudent::Serialize(CArchive& ar){
    //调用基类的Serialize()确保对象的继承部分被序列化
    CObject::Serialize(ar);
    if(ar.IsStoring())
      ar<<m_Name<<m_Num;
    else
      ar>>m_Name>>m_Num;
    <3>在类声明中,添加DECLARE_SERIAL宏
    在类的声明中,添加DECARE_SERIAL宏,以类名为唯一参数,其代码如下:
    class CStudent:public CObject{
    DECLARE_SERIAL(CStudent)
    ...
    }
    <4>定义不带参数的构造函数
    在类的声明中定义一个默认构造函数(不带任何参数的构造函数)。一般情况下,添加类时会自动生成。当从数据文件读入数据时,应用程序框架需要一个默认构造函数对象。
    (如果开发人员没有在使用宏的类中定义默认的构造函数,编译器会在宏IMPLEMENT_SERIAL所在的行警告没有定义默认构造函数。)
    <5>在类的实现文件中,添加IMPLEMENT_SERIAL宏
     在类的实现文件(.cpp文件)中,添加IMPLEMENT_SERIAL宏,它需要3个参数,分别是需要序列化的类名。其基类名及版本号。用于类的数据成员或文档数据在程序不同版本中可能不同,那么序列化内容也不同。如果保存的数据与读取对象的版本数据不同,序列化操作会出现严重错误。因此,应用程序应该使用版本号,它代表了数据的组成和类的结构。基实现代码如下:
    IMPLEMENT_SERIAL(CStudent,CObject,1) //让此类有序列化能力

    展开全文
  • mfc serialize() 函数的使用

    千次阅读 2010-03-03 15:15:00
    vc提供了非常方便的串行化函数serialize().但是在使用的时候,有很多地方需要注意。Serialize(CArchive &ar)函数的声明。本人在使用的时候发现,ARarar>>min;min为基本类型DWORD ,BYTE,INT,FLOAT,DOUBLE,CHAR 还有...

    vc提供了非常方便的串行化函数serialize().

    但是在使用的时候,有很多地方需要注意。Serialize(CArchive &ar)函数的声明。

    本人在使用的时候发现,AR<<"基本类型";

    ar<<min;

    ar>>min;

    min为基本类型DWORD ,BYTE,INT,FLOAT,DOUBLE,CHAR

     

     

     

    还有一个问题,就是Serialize(CArchive &ar)使用时,要进行两处声明

     DECLARE_SERIAL(CGraphBlock)

    IMPLEMENT_DYNAMIC(CGraphBlock, CObject,0)

    CGraphBlock是使用这个串行化读写的类名,必须继承于CObject

     

    当然如果你的类中已经声明了DECLARE_DYNCREATE(CGraphBlock)

    那么就不需要DECLARE_SERIAL(CGraphBlock)了

    但是在类的CPP文件中一定要IMPLEMENT_DYNAMIC(CGraphBlock, CObject,0)

     

     

    这个后面的一个常数,我查了好多资料。仍然不是很了解,有的时候你使用其他值就会出现异常,用0最为保险

     

     

     

     

     

    展开全文
  • MFCSerialize机制及其使用

    千次阅读 2020-06-11 16:48:16
    MFC提供了非常方便的串行化函数Serialize()。利用这个机制可以很方便的对文档进行存取和读取。 Serialization就是面向对象世界里面的永久生存机制,对象必须能够永久生存,也就是他们必须能够在程序结束时存储到文件...

    一、CArchive类介绍

    https://blog.csdn.net/weixin_45525272/article/details/106481559

    二、序列化(Serialization)

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

    1、 序列化提出和定义

    序列化在面向对象的程序设计中出现的,它基于对象是可以连续的思想,在程序退出或者启动的时候,可以把对象顺序的存储在磁盘或者从磁盘读出,存储和读出对象的过程叫做序列化。

    2、 序列化存储的应用和局限

    序列化存储可以把对象存储到磁盘上,但它并不能代替数据库设计的信息存储,因为它只是顺序的存取,没有检索机制。

    3、 序列化的类

    序列化的类可以直接或者间接从CObject类派生,类的声明中必须包含DECLARE_SERIAL 宏调用,实现文件也必须有与之对应的宏:
    IMPLEMENT_SERIAL。(注意: DECLARE_SERIAL/IMPLEMENT_SERIAL包含了DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏)。

    4、 MFC中序列化的使用

    如果应用程序没有进行直接磁盘操作的输入输出,而是依靠序列化的过程,那么就不必直接使用CFile对象。MFC库中文档类的Serialize函数和CFile对象之间有一个CArchive对象。该对象为CFile对象缓冲数据并保持一个内部标志,来指明是存储或者加载对象。MFC应用程序框架负责CFile和Carchive对象构造及关联。在自动生成的菜单File Open 和FileSave等过程中,应用程序框架会调用文档的Serialize函数,我们可以在该函数中处理特定类对象的序列化。

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

    5、遵循步骤

    一个类要支持Serializable,必须遵循以下步骤:
    该类必须要继承自CObject
    在该类的头文件中添加DECLARE_SERIAL宏
    在该类的实现文件中添加 IMPLEMENT SERIAL宏
    为该类添加一个缺省构造函数
    在该类中重写Serialize( CArchive& ar )函数
    之后,该类就可以被Serializable。
    如何使用:
    譬如我们新建一个MFC应用程序,为了方便处理数据,我们在程序中单独创建自己的类MyClass:

    MyClass:public CObject
    {
    DECLARE_SERIAL(MyClass)     //很重要一定要加上
    public:
    
       virtual void Serialize(CArchive& ar);
    
    public:
       int m_iVal;
       float m_fVal;
    
    };
    

    在实现文件中:

    
    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:

    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对象了:

    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加载机制:

    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保存机制:

    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);
    
    展开全文
  • MFCSerialize序列化函数

    千次阅读 2017-07-02 18:16:18
    MFC库中文档类的Serialize函数和CFile对象之间有一个CArchive对象。该对象为CFile对象缓冲数据并保持一个内部标志,来指明是存储或者加载对象。MFC应用程序框架负责CFile和Carchive对象构造及关联。在自动生成的菜单...

    一、实现步骤:

    要实现一个能够序列化的类,必须要经过一下几步

    1.这个类必须间接火直接地由CObject派生而来
    2.定义一个不带参数的构造函数
    3.在头文件中,必须有如下声明:
    DECLARE_SERIAL( Your name of class)
    4.在源文件中开头有如下声明
    IMPLEMENT_SERIAL (Your name of class,CObject,1)
    其中的第三个参数代表版本号
    5.必须重载基类中的序列化函数Serialize
    经过以上五步,一个带有存储功能的类就诞生了
     

    二、序列化(Serialization)

    1、 序列化提出和定义
    序列化在面向对象的程序设计中出现的,它基于对象是可以连续的思想,在程序退出或者启动的时候,可以把对象顺序的存储在磁盘或者从磁盘读出,存储和读出对象的过程叫做序列化。
       
    2、 序列化存储的应用和局限
           序列化存储可以把对象存储到磁盘上,但它并不能代替数据库设计的信息存储,因为它只是顺序的存取,没有检索机制。
     
    3、 序列化的类
    序列化的类可以直接或者间接从CObject类派生,类的声明中必须包含DECLARE_SERIAL 宏调用,实现文件也必须有与之对应的宏:
    IMPLEMENT_SERIAL。(注意: DECLARE_SERIAL/IMPLEMENT_SERIAL包含了DECLARE_DYNAMIC/IMPLEMENT_DYNAMIC宏)。
     
    4、 MFC中序列化的使用
    如果应用程序没有进行直接磁盘操作的输入输出,而是依靠序列化的过程,那么就不必直接使用CFile对象。MFC库中文档类的Serialize函数和CFile对象之间有一个CArchive对象。该对象为CFile对象缓冲数据并保持一个内部标志,来指明是存储或者加载对象。MFC应用程序框架负责CFile和Carchive对象构造及关联。在自动生成的菜单File Open 和FileSave等过程中,应用程序框架会调用文档的Serialize函数,我们可以在该函数中处理特定类对象的序列化。
    下面是摘自vc技术内幕上的代码:
    void CStudentDoc::Serialize(CArchive& ar)
    {
        TRACE("Entering CStudentDoc::Serialize\n");
    if (ar.IsStoring())
    {
            // TODO: add storing code here
    }
    else
    {
            // TODO: add loading code here
    }
        m_studentList.Serialize(ar);
    }


    三、调用

    MFC程序在打开或关闭文件操作的时候,会调用该函数。默认的该函数并没有对我们自己的数据(m_studentList)进行存取。我们在该函住中加入的最后一行代码序列化了我们的数据对象。当然这都需要我们自己编写自己数据类的Serialize函数。如下:(摘自vc技术内幕上的代码)

    void CStudent::Serialize(CArchive& ar)
    {
        TRACE("Entering CStudent::Serialize\n");
        if (ar.IsStoring()) {
            ar << m_strName << m_nGrade;
        }
        else {
            ar >> m_strName >> m_nGrade;
        }
    }


    展开全文
  • MFC序列化Serialize

    2016-12-16 21:33:59
    序列化Serialize使用介绍 创建可序列化的类 使类可序列化需要五个主要步骤。下面列出了这些步骤并在以后章节内进行了解释: 从 CObject 派生类(或从 CObject 派生的某个类中派生)。重写 Seria
  • 使用MFC的document/View框架中内的Serialize函数,这称为隐式创建。2.显示创建就是直接申明一个与CFile对象相关联的对象。 隐式方法就是直接使用框架中CMyDocument类的Serialize(),这里要强调的是,如果 ...
  • 当我们新建一个基于文档的MFC程序时,向导会自动为我们创建一些菜单,点击菜单的保存或者打开文件按钮时,内部机制自动触发Serialize函数调用,那么怎样在程序中自己触发Serialize呢? 剖开文件保存和打开内部...
  • MFC关于文件读写的操作,可以使用Serialize函数: void CGraphicApp::Serialize(CArchive& ar) { if (ar.IsStoring()) { // storing code int i = 0; ar << i; } else { //...
  • MFC对可Serialize类型的版本控制

    千次阅读 2012-04-10 15:32:53
    使用MFC提供的Serialize功能对类型进行序列化/反序列化非常的方便。当软件升级后,Serialize的内容可能也会发生变化,这时,就可以使用MFC提供的版本控制功能解决反序列化因为内容不同引起的冲突了。 编写可序列化...
  • MFC文件读写——Serialize

    千次阅读 2014-08-21 14:28:52
    欲让一个对象有Serialize 能力,它必须衍生自一个Serializable 类别。一个类别意欲成 为Serializable,必须有下列五大条件;至于其原因,前面的讨论已经全部交待过了。 1. 从CObject 衍生下来。如此一来可保有RTTI...
  • 必须为希望串行化的每个类覆盖Serialize。被覆盖的Serialize首先必须调用基类的Serialize函数。 在类的声明中必须使用DECLARE_SERIAL宏,并且在类的执行过程中也必须使用IMPLEMENT_SERIAL宏。 使用CArchive::Is...
  • 是不是除了从CObject派生的类以外的数据,都可以直接使用重载的<<和>>进行存取?...其他的,比如自己从CObject派生的类和CArray,CList,CFont等都要调用serialize函数? 那CRect,CSize等呢?
  • void CFirstDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: 在此添加存储代码 /*ar << 1; CString str = _T("Hello"); ar << str; */ POSITION pos = ...
  • 2.Serialize()调用过程 文件打开菜单命令->CWinApp::OnFileOpen(m_pDocManager->OnFileOpen()) ->CDocManager::OnFileOpen(调用DoPromptFileName函数显示文件打开对话框->AfxGetApp()->OpenDocumentFile) ->...
  • 最近CObList类串行化时出了一点问题,但是从网上找不到CObList::Serialize的源代码,现在将《输入浅出MFC》中的函数列于下方,方便查看。 void CObList::Serialize(CArchive&amp; ar) { ASSERT_VALID(this); ...
  • MFC 创建可序列化的对象 Serialize用法

    千次阅读 2012-02-15 16:43:41
    virtual void Serialize(CArchive& ar); //第四步,重写序列化函数 virtual ~CPerson(void); CString m_name; int m_age; bool m_gender; private: CString m_words; }; Person....
  • Serialize序列化函数(MFC

    千次阅读 2017-01-08 23:49:54
    MFC库中文档类的Serialize函数和CFile对象之间有一个CArchive对象。该对象为CFile对象缓冲数据并保持一个内部标志,来指明是存储或者加载对象。MFC应用程序框架负责CFile和Carchive对象构造及关联。在自动生成的菜单...
  • 我新建了一个MFC的多文档工程,View继承CEditView,Doc继承CDocument,现在打开文件默认都是串行化,我想打开.txt或者是一些其他后缀的文本文件需要怎么改 当前的Doc类中的序列化如下,最好是改序列化,我以前做...
  • 1、首先在头文件里面声明 DECLARE_SERIAL...2、重写CObject的Serialize函数 virtual void Serialize(CArchive& ar) { CObject::Serialize(ar); //关键代码 if(ar.IsStoring())  { //序...
  • void CMFCApplication6Doc::Serialize(CArchive& ar) 在点击保存和打开时会调取此处的代码 1 void CMFCApplication6Doc::Serialize(CArchive& ar) 2 { 3 if (ar.IsStoring()) 4 { 5 //...
  •  不知不觉跟随者侯捷的脚步对着电子书看了将近600页,就一个感觉:云里雾里。函数调用一层嵌一层,还有那该死的virtual关键字,每次调用时都得长个心眼...吐槽归吐槽,MFC设计之精巧不容质疑,其中的RTTI(Running Ti

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,711
精华内容 1,084
关键字:

mfc的serialize