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

  • 相关阅读:
    软件測试系列之软件測试过程模型(四)
    实例具体解释Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)
    Hadoop-2.2.0中文文档—— MapReduce 下一代
    const vs readonly
    oracle-asm
    Javascript 笔记与总结(2-15)结构、样式、行为分离
    [Swift]LeetCode455. 分发饼干 | Assign Cookies
    [Swift]LeetCode453. 最小移动次数使数组元素相等 | Minimum Moves to Equal Array Elements
    [Swift]LeetCode448. 找到所有数组中消失的数字 | Find All Numbers Disappeared in an Array
    [Swift]LeetCode443. 压缩字符串 | String Compression
  • 原文地址:https://www.cnblogs.com/bluejoe/p/5116036.html
Copyright © 2011-2022 走看看