友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

VC语言6.0程序设计从入门到精通-第39部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


类的重载插入运算符和提取运算符,因此也可以直接使用这两个运算符进行串行化。  



     (3 )自定义的类  

     如果序列化的类中包含其他自定义的内嵌对象,则需要处理后再进行串性化。例如在 

CSampleData 类中添加如下的新数据成员:  



    public:  



         CSampleChildData m_data;  



    将   CSampleData  类串行化时,需要对             CSampleChildData  进行额外的处理。首先使得 

CSampleChildData 继承 CObject,然后编写它自己的 Serialize()成员函数。这时 CSampleData 

类的 Serialize()函数可以进行如下修改以实现对 m_data 的串行化:  



    void CSampleData::Serialize(CArchive& ar)  



     {  



         CObject::Serialize(ar);   //进行基类的序列化  



         if (ar。IsStoring()) {  



             ar  m_strName 》》 m_nType;  //读取数据  



         }  



                                                                                   ·179 ·  


…………………………………………………………Page 191……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



         m_Data。Serialize(ar);            // 串行化 m_Data  



     }  



     如果 CSampleData 类中的 CSampleChildData 对象是通过指针在堆中创建的,则代码如下:  



     public:  



         CSampleChildData *m_pData;  



     将 CSampleData 类串行化更为简单。首先需要为 CSampleChildData 添加串行化代码,即 

继承  CObject,并添加相应的宏和构造函数,最后编写 CSampleChildData                             自己的 Serialize() 

函数。完成对  CSampleChildData          的修改后就可以在  CSampleData             类的    Serialize()函数中用 

CArchive 的插入和提取运算符进行串行化。代码如下:  



     void CSampleData::Serialize(CArchive& ar)  



     {  



         CObject::Serialize(ar);   //进行基类的序列化  



         if (ar。IsStoring()) {  



              ar 》 m_nType 》》 m_pData;  //读取数据  



         }  



     }  



     在上述代码 中,之所以 能对自定义 的类进行插 入和提取运 算,是因为 在添加的 

DECLARE_SERIAL()和 IMPLEMENT_SERIAL()宏中包含了对插入和提取运算符的重载 。当 

CSampleChildData 对象被写进文件时,这两个宏保证类名和数据一起被写进去 ;而当从文件 

中读入时,类名被读进来,相应的类的对象被动态构造,这些也是由这两个宏包含的代码实 

现的。当 CSampleChildData 对象被构造后,就可以通过  Serialize() 自动进行串行化,这是由 

于 CArchive 的插入和提取运算符对 CObject 类型进行了重载。最后新建的 CSampleChildData 

对象的指针即保存在 m_pData  中。根据上面的分析,对于自定义的类,不能对类的实例对象 

使用插入和提取运算符,而只能对类的指针进行这样的操作。  



     (4 )集合类  

     由于所有的集合类都是从 CObject 类派生出来的,而且集合类都包含了与串行化有关的 

宏调用,因此就可以通过调用集合类的 Serialize()成员函数,方便地对集合进行串行化 。例如 

一个由 CSampleData 对象组成的 CArray 集合,调用 CArray 的 Serialize()函数,就可以使得每 

个 CSampleData 对象的 Serialize()函数被依次调用,从而完成对集合类的序列化。  



8。1。3    CArchive 类  



     在前面的章节中已有关于 CArchive 类的介绍,该类提供了一个类型安全的访问 CFile 对 

象(CFile 对象是 Visual C++ 中的基本文件对象,将在 8。2 节中详细介绍)的机制,用于将可 

串行化对象写入 CFile 对象或者从中读取可串行化对象 。给定的 CArchive 对象可以存储数据, 

也可以加载数据,但不允许同时进行,而且其寿命也只限于将对象写入文件或从文件读取对 



 ·180 ·  


…………………………………………………………Page 192……………………………………………………………

                                                                                     第 8 章    文件操作  



象的一次性传递。这也就是 MFC 中串行化只能顺序进行的原因。  

     下面介绍 Carchive 类的一些主要功能。  



     1.构造函数  



     Carchive 类通过构造函数从已打开的 CFile 对象中创建可以向该 CFile 对象进行串行化的 

新对象。其原型为:  



     CArchive(  



           CFile* pFile;  



           UINT nMode;  



           int nBufSize = 4096;  



           void* lpBuf = NULL    



     );  



     o  参数 pFile 指向需要进行串行化的 CFile 对象。  

     o  参数 nMode 设置创建对象的标志,如果设置了这个标志,则必须在销毁前调用 Close 

        函 数 , 否 则 数 据 将 会 损 坏 。 若 取 值 为                  CArchive::load : 从 文 件 中 读 取 数 据 ; 

        CArchive::store :向文件中保存数据;CArchive::bNoFlushOnDelete :防止 CArchive 对 

        象在被销毁时自动调用 Flush 函数进行更新。  

     o  参数 nBufSize 设置缓冲区大小。  

     o  参数 lpBuf 用于自定义缓冲区,取值为 NULL 则由 CArchive  自行处理。  

     下面是一段示例代码:  



     CFile file;  



     file。Open(〃1。dat〃; CFile::modeWrite);  //打开 1。dat 文件进行写操作  



     CArchive archive(&file; CArchive::stroe);;  //创建一个对 file 进行数据保存的文档对象  



     2 .读写函数  



     (1)插入运算符(》 )  

     这两个运算符分别用于保存和读取数据,在原型中可以看到 CArchive 类为许多数据类型 

进行了重载,这为数据的串行化提供了基础。  



     (2 )Read()和 Write() 函数  

     这两个函数分别从文件中读取或写入原始的字节块。原型为:  



     UINT Read(  



           void* lpBuf;  



           UINT nMax    



     );  



     void Write(  



           const void* lpBuf;  



           UINT nMax    



     );  



     o  参数 lpBuf :给出字节块的指针,用于保存数据或者从中读取数据。  



                                                                                               ·181 ·  


…………………………………………………………Page 193……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



    o  参数 nMax :用于确定最大的读写字节数。  

    o  Read()函数返回值:返回实际读写的字节数。  



    (3 )Flush() 函数  

    该函数用于将缓冲区剩余的数据强制写入文件中。原型为:  



    void Flush( );  



    注意该函数只保证数据完全传送到指定的 CFile 对象中,而且必须通过 CFile::Close 才能 

完成最终向磁盘写入数据的过程。  



    3 .状态和标志函数  



    该类函数主要有 IsLoading()和 IsStoring()两个函数,这两个函数分别用于确定 CArchive 

对象是否处于读取状态,或者是否处于保存状态。其原型分别为:  



    BOOL IsLoading( ) const;  



    BOOL IsStoring( ) const;  



    4 .Close()函数  



    该函数用于清空缓冲区,关闭 CArchive 对象,并且将 CArchive 对象与 CFile 对象分离。 

其原型为:  



    void Close( );  



8。1。4    加入串行化代码  



    介绍完串行化的基本内容,本节将讲述如何在文档视图应用程序中添加文档类的串行化 

功能的方法来实现文档的保存和读取。  

    在 MFC 中,文档数据进行串行化的处理过程,同样是通过文档类的 Serialize()函数进行。 

下面以选择“文件|另存为”菜单命令为例介绍这个过程。首先 MFC 框架提示用户选取文件 

名,并打开对应的 CFile 对象。接着框架创建指向该 CFile 对象的 CArchive 对象。由于是“另 

存为”,因此该对象设置为“存储 ”,即 CArchive::store 。然后调用 CDocument 派生类即程序 

的文档类中定义的 Serialize()函数,将 CArchive 对象的引用传递给该函数。程序的文档类的 

Serialize()函数执行完毕后,框架先销毁 CArchive 对象,再销毁 CFile 对象。  

    因此,根据上述过程,在文档视图应用程序中进行文档的串行化处理,只需要在文档类 

中重载 CDocument::Serialize()函数,对特定的文档数据进行串行化即可实现。下面给出一个 

在文档类中加入串行化代码的示例代码。该段代码中 CSampleDoc 类是程序的文档类,它有 

一个 CSampleData 类的成员变量指针,用于保存文档数据。示例演示了 CSampleDoc 类如何 

将 CSampleData 类的文档数据串行化。  



    1.CSampleData 类的声明  



    具体代码如下:  



    class CSampleData : public CObject      



    {  



    public:  



 ·182 ·  


…………………………………………………………Page 194……………………………………………………………

                                                                                                         第 8 章    文件操作  



       //定义的公共数据类型  



       CString m_strName;  



       int m_nType;  



  



       CSampleData();  



       virtual ~CSampleData();  



         



       //定义串行化的宏  



       DECLARE_SERIAL(CSampleData)  



         



       // 串行化虚函数  



       virtual void Serialize(CArchive &ar);  



};  



2 .CSampleData 类的实现  



具体代码如下:  



//实现串行化的宏  



IMPLEMENT_SERIAL(CSampleData; CObject; 0)  



  



//初始化  



CSampleData::CSampleData()  



{  



       m_nType=0;  



       m_strName=〃〃;  



}  



  



CSampleData::~CSampleData()  



{  



  



}  



  



// 串行化函数  



void CSampleData::Serialize(CArchive &ar)  



{  



       //基类的串行化  



       CObject::Serialize(ar);  



       if (ar。IsStoring())  



       {  



              //存储数据  



              arm_strName;  



              }  



       }  



       3 .CSampleDoc 类的声明  



       具体代码如下:  



       class CSampleDoc : public CDocument  



        {  



       protected: // create from serialization only  



              CSampleDoc();  



              DECLARE_DYNCREATE(CSampleDoc)  



         



       // Attributes  



       public:  



         



       // Operations  



       public:  



         



       // Overrides  



              // ClassWizard generated virtual function overrides  



              //{{AFX_VIRTUAL(CSampleDoc)  



              public:  



              virtual BOOL OnNewDocument();  



              virtual void Serialize(CArchive& ar);  



              //}}AFX_VIRTUAL  



         



       // Implementation  



       public:  



              CSampleData *m_pData;                       //这里加入自定义文档数据  



         



              virtual ~CSampleDoc();  



       #ifdef _DEBUG  



              virtual void AssertValid() const;  



              virtual void Dump(CDumpContext& dc) const;  



       #endif  



         



 ·184 ·  


…………………………………………………………Page 196……………………………………………………………

                                                                                                              第 8 章    文件操作  



protected:  



  



// Generated message map functions  



protected:  



       //{{AFX_MSG(CSampleDoc)  



              // NOTE the ClassWizard will add and remove member functions here。  



              //        DO NOT EDIT what you see in these blocks of generated code !  



       //}}AFX_MSG  



      
返回目录 上一页 下一页 回到顶部 1 2
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!