6.3.4 使用MFC::CArchive
準確地說(shuō),CArchive也屬于二進(jìn)制變長(cháng)數據,由于CArchive采用了CObject的RTTI特性,同時(shí)存儲了對象類(lèi)的信息,因此它對于CObject對象的持久化和反持久化來(lái)說(shuō),的確是"很好很強大"。
早在第3章我們結合CObject討論過(guò)CArchive的相關(guān)知識,要想用上CArchive的強大功能,我們需要做的僅僅是將自己的類(lèi)定義成支持自創(chuàng )建的CObject子類(lèi),并且覆蓋默認的Serialize()函數。
現在動(dòng)手
以下我們將準備一個(gè)示例,使用CArchive實(shí)現CPerson對象的持久化和反持久化。
選擇【W(wǎng)in32】→【W(wǎng)in32項目】→【控制臺程序】命令,創(chuàng )建ArchiveTest。
新建CPerson類(lèi),CPerson的定義如下:
- class CPerson : public CObject
- {
- DECLARE_SERIAL(CPerson)
- private:
- CString _name;
- int _age;
- bool _gender;
- CString _words;
- public:
- CPerson();
- CPerson(CString name, int age, bool gender = true);
- CString getName();
- CString getWords();
- void setWords(CString words);
- int getAge();
- bool isMale();
- void say();
- void say(CString msg);
- virtual void Serialize(CArchive& ar);
- };
CPerson類(lèi)的實(shí)現如下:
- #include "stdafx.h"
- #include "mfc-person.h"
- IMPLEMENT_SERIAL(CPerson, CObject, 1)
- CPerson::CPerson()
- {
- _name = _T("無(wú)名氏");
- _age = 0;
- _gender = true;
- }
- CPerson::CPerson(CString name, int age, bool gender)
- {
- _name = name;
- _age = age;
- _gender = gender;
- }
- CString CPerson::getName()
- {
- return _name;
- }
- CString CPerson::getWords()
- {
- return _words;
- }
- void CPerson::setWords(CString words)
- {
- _words = words;
- }
- int CPerson::getAge()
- {
- return _age;
- }
- bool CPerson::isMale()
- {
- return _gender;
- }
- void CPerson::say()
- {
- say(_words);
- }
- void CPerson::say(CString msg)
- {
- _tprintf(_T("%s: %s\r\n"), _name, msg);
- }
- void CPerson::Serialize(CArchive& ar)
- {
- if (ar.IsStoring())
- {
- ar << this->_name<<this->_age<<this->_gender << this->_words;
- }
- else
- {
- ar >> this->_name>>this->_age>>this->_gender >> this->_words;
- }
- }
修改主程序,在main()中創(chuàng )建兩個(gè)CPerson對象,然后將其持久化到文件中,再將其從文件中反持久化出來(lái),調用對象的方法,試試它們還是不是活的:
- #include "stdafx.h"
- #include "mfc-person.h"
- #include "ArchiveTest.h"
- int main()
- {
- setlocale(LC_ALL, "chs");
- //創(chuàng )建兩個(gè)待寫(xiě)入的對象
- CPerson tong(_T("佟湘玉"), 28, false);
- tong.setWords(_T("額滴神啊..."));
- CPerson bai(_T("白展堂"), 27, true);
- bai.setWords(_T("葵花點(diǎn)穴手!"));
- //準備寫(xiě)入
- CFile oFile(_T("persons.archive"),CFile::
modeCreate|CFile::modeWrite);- CArchive oar(&oFile, CArchive::store);
- //序列化進(jìn)去了
- oar << &tong << &bai;
- //oar.WriteObject(&tong);
- //oar.WriteObject(&bai);
- oar.Close();
- oFile.Close();
- //準備讀取
- CFile iFile(_T("persons.archive"), CFile::modeRead);
- CArchive iar(&iFile, CArchive::load);
- CPerson *p1, * p2;
- //序列化出來(lái)了
- iar >> p1 >> p2;
- //p1 = iar.ReadObject(RUNTIME_CLASS(CPerson));
- //p2 = iar.ReadObject(RUNTIME_CLASS(CPerson));
- //看看他們是不是活的*_*ii
- p1->say();
- p2->say();
- delete p1;
- delete p2;
- }
運行結果如圖6-19所示,可以看出,作為被序列化的CPerson對象,佟掌柜和老白完完全全活過(guò)來(lái)了。
![]() |
| 圖6-19 運行結果 |
比較好奇的讀者可以查看一下其生成的二進(jìn)制文件,這個(gè)persons.archive看起來(lái)比較亂,但根據運行結果中佟湘玉和白展堂說(shuō)的兩句話(huà),我們不必擔心該存儲方式的準確性,CArchive生成的二進(jìn)制內容如圖6-20所示。
![]() |
| (點(diǎn)擊查看大圖)圖6-20 CArchive生成的二進(jìn)制內容 |
- _AFX_INLINE CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb)
- {
- ar.WriteObject(pOb);
- return ar;
- }
- _AFX_INLINE CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb)
- {
- pOb = ar.ReadObject(NULL);
- return ar;
- }
感興趣的程序員可以究根求源,打開(kāi)CArchive的源碼,就會(huì )發(fā)現WriteObject()和ReadObject()會(huì )反過(guò)來(lái)調用CObject的Serialize()函數,調用流程如圖6-21所示。
![]() |
| (點(diǎn)擊查看大圖)圖6-21 CArchive的調用流程 |
===========================================
聯(lián)系客服