zoukankan      html  css  js  c++  java
  • 6.3.4 使用MFC::CArchive

    6.3.4  使用MFC::CArchive

    准确地说,CArchive也属于二进制变长数据,由于CArchive采用了CObject的RTTI特性,同时存储了对象类的信息,因此它对于CObject对象的持久化和反持久化来说,的确是"很好很强大"。

    早在第3章我们结合CObject讨论过CArchive的相关知识,要想用上CArchive的强大功能,我们需要做的仅仅是将自己的类定义成支持自创建的CObject子类,并且覆盖默认的Serialize()函数。

    现在动手

    以下我们将准备一个示例,使用CArchive实现CPerson对象的持久化和反持久化。

    选择【Win32】→【Win32项目】→【控制台程序】命令,创建ArchiveTest。

    新建CPerson类,CPerson的定义如下:

    1. class CPerson : public CObject  
    2. {  
    3. DECLARE_SERIAL(CPerson)  
    4. private:  
    5.     CString _name;  
    6.     int _age;  
    7.     bool _gender;  
    8.     CString _words;  
    9. public:  
    10.     CPerson();  
    11.     CPerson(CString name, int age, bool gender = true);  
    12.     CString getName();  
    13.     CString getWords();  
    14.     void setWords(CString words);  
    15.     int getAge();  
    16.     bool isMale();  
    17.     void say();  
    18.     void say(CString msg);  
    19.     virtual void Serialize(CArchive& ar);  
    20. }; 

    CPerson类的实现如下:

    1. #include "stdafx.h"  
    2. #include "mfc-person.h"  
    3.  
    4. IMPLEMENT_SERIAL(CPerson, CObject, 1)  
    5.  
    6. CPerson::CPerson()  
    7. {  
    8.     _name = _T("无名氏");  
    9.     _age = 0;  
    10.     _gender = true;  
    11. }  
    12.  
    13. CPerson::CPerson(CString name, int age, bool gender)  
    14. {  
    15.     _name = name;  
    16.     _age = age;  
    17.     _gender = gender;  
    18. }  
    19.  
    20. CString CPerson::getName()  
    21. {  
    22.     return _name;  
    23. }  
    24.  
    25. CString CPerson::getWords()  
    26. {  
    27.     return _words;  
    28. }  
    29.  
    30. void CPerson::setWords(CString words)  
    31. {  
    32.     _words = words;  
    33. }  
    34.  
    35. int CPerson::getAge()  
    36. {  
    37.     return _age;  
    38. }  
    39.  
    40. bool CPerson::isMale()  
    41. {  
    42.     return _gender;  
    43. }  
    44.  
    45. void CPerson::say()  
    46. {  
    47.     say(_words);  
    48. }  
    49.  
    50. void CPerson::say(CString msg)  
    51. {  
    52.     _tprintf(_T("%s: %s/r/n"), _name, msg);  
    53. }  
    54.  
    55. void CPerson::Serialize(CArchive& ar)  
    56. {  
    57.     if (ar.IsStoring())  
    58.     {  
    59.         ar << this->_name<<this->_age<<this->_gender << this->_words;  
    60.     }  
    61.     else 
    62.     {  
    63.         ar >> this->_name>>this->_age>>this->_gender >> this->_words;  
    64.     }  

    修改主程序,在main()中创建两个CPerson对象,然后将其持久化到文件中,再将其从文件中反持久化出来,调用对象的方法,试试它们还是不是活的:

    1. #include "stdafx.h"  
    2. #include "mfc-person.h"  
    3. #include "ArchiveTest.h"  
    4.  
    5. int main()  
    6. {  
    7.     setlocale(LC_ALL, "chs");  
    8.  
    9.     //创建两个待写入的对象  
    10.     CPerson tong(_T("佟湘玉"), 28, false);  
    11.     tong.setWords(_T("额滴神啊..."));  
    12.  
    13.     CPerson bai(_T("白展堂"), 27, true);  
    14.     bai.setWords(_T("葵花点穴手!"));  
    15.  
    16.     //准备写入  
    17.     CFile oFile(_T("persons.archive"),CFile::
      modeCreate|CFile::modeWrite);  
    18.     CArchive oar(&oFile, CArchive::store);  
    19.  
    20.     //序列化进去了  
    21.     oar << &tong << &bai;  
    22.     //oar.WriteObject(&tong);  
    23.     //oar.WriteObject(&bai);  
    24.  
    25.     oar.Close();  
    26.     oFile.Close();  
    27.  
    28.     //准备读取  
    29.     CFile iFile(_T("persons.archive"), CFile::modeRead);  
    30.     CArchive iar(&iFile, CArchive::load);  
    31.  
    32.     CPerson *p1, * p2;  
    33.  
    34.     //序列化出来了  
    35.     iar >> p1 >> p2;  
    36.     //p1 = iar.ReadObject(RUNTIME_CLASS(CPerson));  
    37.     //p2 = iar.ReadObject(RUNTIME_CLASS(CPerson));  
    38.  
    39.     //看看他们是不是活的*_*ii  
    40.     p1->say();  
    41.     p2->say();  
    42.  
    43.     delete p1;  
    44.     delete p2;  

    运行结果如图6-19所示,可以看出,作为被序列化的CPerson对象,佟掌柜和老白完完全全活过来了。

     
    图6-19  运行结果

    比较好奇的读者可以查看一下其生成的二进制文件,这个persons.archive看起来比较乱,但根据运行结果中佟湘玉和白展堂说的两句话,我们不必担心该存储方式的准确性,CArchive生成的二进制内容如图6-20所示。

     
    (点击查看大图)图6-20  CArchive生成的二进制内容

    还有一个问题:为什么我们可以使用"oar << &tong << &bai"和"iar >> p1 >> p2"? 实际上CArchive包含了支持"CObject *"参数的流操作符:

    1. _AFX_INLINE CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb)  
    2. {  
    3.     ar.WriteObject(pOb);  
    4.     return ar;  
    5. }  
    6.  
    7. _AFX_INLINE CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb)  
    8. {  
    9.     pOb = ar.ReadObject(NULL);  
    10.     return ar;  

    感兴趣的程序员可以究根求源,打开CArchive的源码,就会发现WriteObject()和ReadObject()会反过来调用CObject的Serialize()函数,调用流程如图6-21所示。

     
    (点击查看大图)图6-21  CArchive的调用流程

    这正是MFC的精妙之处,它让CPerson不知不觉地就具备了的持久化和反持久化的功能。

    ===========================================

    以上摘自《把脉VC++》 http://www.china-pub.com/195701 第6.3.4小节的内容 ,转载请注明出处。

    如果你想与我交流,请点击如下链接加我为好友:http://student.csdn.net/invite.php?u=113292&c=8913f87cffe7d533

  • 相关阅读:
    通用权限管理设计 之 数据库结构设计
    jQuery LigerUI 插件介绍及使用之ligerDateEditor
    jQuery LigerUI 插件介绍及使用之ligerTree
    jQuery LigerUI V1.01(包括API和全部源码) 发布
    jQuery liger ui ligerGrid 打造通用的分页排序查询表格(提供下载)
    jQuery LigerUI V1.1.5 (包括API和全部源码) 发布
    jQuery LigerUI 使用教程表格篇(1)
    jQuery LigerUI V1.0(包括API和全部源码) 发布
    jQuery LigerUI V1.1.0 (包括API和全部源码) 发布
    nginx keepalived
  • 原文地址:https://www.cnblogs.com/bluejoe/p/5116036.html
Copyright © 2011-2022 走看看