zoukankan      html  css  js  c++  java
  • 实现可串行化类的步骤

    步骤


    我们知道CArchive类可以支持基本类型的串行化,还可以支持派生于CObject类的派生类,想要这个派生类支持可串行化,需要如下步骤即可:


    (1) 从CObject类派生或者从CObject类派生的某个派生类

    (2) 重写Serialize成员函数,把类的数据成员写入文件

    (3) 在类声明中使用“DECLARE_SERIAL”宏

    (4) 定义不带参数的构造函数

    (5) 在类的实现文件中使用“IMPLEMENT_SERIAL”宏


    关于SERIAL宏


    IMPLEMENT_SERIAL的形式如下:

    IMPLEMENT_SERIAL( class_name, base_class_name, wSchema )
    参数: 
    class_name            类的实际名字(不用引号括起来)。  
    base_class_name 基类的名字(不用引号括起来)。  
    wSchema                 一个UINT类型的版本号。


    DECLARE_SERIAL的形式如下:

    DECLARE_SERIAL(class_name)
    参数: 

    class_name  类的实际名字

    这两个宏都是为动态的CObject派生类对象生成必要的C++代码,包括加载数据数据使new对象等操作。


    实例


    下面我们将“图形重绘和保存”这篇博文的CGraph对象串行化,使之我们能够永久保证数据对象,其具体串行化关键代码如下:

    //Graph.h

    //(1)派生于CObject类
    class CGraph:public CObject
    {
    public:
        //(3)声明中使用DECLARE_SERIAL宏
        DECLARE_SERIAL(CGraph)
    
        //(4)定义无参的构造函数
        CGraph(void);
        CGraph(CPoint ptBegin, CPoint ptEnd, int DrawType);
        ~CGraph(void);
    
        //(2)重写Serialize成员函数
        virtual void Serialize(CArchive& ar);
    ...
    private:
        CPoint m_ptBegin;
        CPoint m_ptEnd;
        int   m_DrawType;
    };


    //Graph.cpp文件代码

    #include "StdAfx.h"
    #include "Graph.h"
    //(5)实现文件中使用“IMPLEMENT_SERIAL”宏
    IMPLEMENT_SERIAL(CGraph, CObject, 1)
    
    CGraph::CGraph(void)
    {
        m_DrawType = 0;
    }
    
    //Call your base class version of Serialize to make sure that the inherited portion of the object is serialized. 
    //Insert or extract the member variables specific to your class. 
    void CGraph::Serialize(CArchive& ar)
    {
        // call base class function first
        // base class is CObject in this case
        CObject::Serialize(ar);
    
        // now do the stuff for our specific class
        if (ar.IsStoring())//保存文件时执行
        {
            ar << m_DrawType << m_ptBegin << m_ptEnd;
        } 
        else
        {
            ar >> m_DrawType >> m_ptBegin >> m_ptEnd;//加载时数据从硬盘中加载到内存
        }
    }

    我们在提取和插入类对象时,需要使用指针对象,形如:

    CGraph *pGraph;
    ar << pGraph;//保存数据
    ar >> pGraph;//提取数据


    在提取数据时,框架会调用IMPLEMENT_SERIAL 宏,这个宏背后会帮助我们new 一个指定的对象,并将指针返回给pGraph,因此我们不要为这个指针变量分配内存空间,我们进行提取(>>)和插入(<<)行为时,会发生>>或者<<运算符重载,在运行符重载过程中会有执行“pOb->Serialize(*this)”这个语句,pOb这里是CGraph对象,其中serialize是CObject 类的成员函数,它是个虚函数;CGraph类继承于CObject,因此最终在保存对象的数据时,实际上调用的是CGraph类的serialize函数,这种调用是由框架自动完成的,从而将类对象数据写入文件,完成永久化保存。


    实现重绘和保存的基本原理


    1.点击保存时,Document类将内存中的绘图参数信息写到指定的文件名,从而永久性的保存;

    2.点击打开时,Document类将从指定文本中加载CGraph参数信息到指定指针变量,当数据加载全部完成后,View中的OnDraw虚函数中负责图形重新显示,即调用CGraph的DrawItem接口完成图形重绘。


    实例代码下载地址:

    http://download.csdn.net/download/xiao3404/9886827


  • 相关阅读:
    漫谈计算机组成原理(九)定点数及定点数的运算
    漫谈计算机组成原理(八)原码、补码、反码
    漫谈计算机组成原理(七)I/O系统
    漫谈计算机组成原理(六)数据校验方法
    漫谈计算机组成原理(五)高速缓冲存储器
    漫谈计算机组成原理(四)主存
    致计算机专业准大一新生
    购物车原理以及实现
    Ajax发送PUT/DELETE请求时出现错误的原因及解决方案
    浅谈乱码原因及解决方案
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468333.html
Copyright © 2011-2022 走看看