?? chap7_4.htm
字號:
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=gb_2312-80">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>7.4 定制串行化</title>
<link rel="stylesheet" href="../../../cpcw.css"></head>
<body link="#3973DE" alink="#3973DE" background="../../bg.gif">
<div align="center"><center>
<table border="0" cellpadding="0" cellspacing="0" width="85%">
<tr bgcolor="#FFFFFF">
<td>
<div align="center"><center><table border="0"
cellpadding="0" cellspacing="0" width="615" height="20">
<tr>
<td width="377" bgcolor="#15397D" height="20"><font
size="5"></font> </td>
<td width="238" bgcolor="#000000" height="20">
<p
align="right"><a href="../../vc.htm"><span style="text-decoration: none"><font
color="#FFFFFF">電腦報(bào)Visual C++網(wǎng)絡(luò)教程</font></span></a></p>
</td>
</tr>
</table>
</center></div>
<p align="center"><font color="#FF3333" face="Times New Roman"><b>7.4</b></font><b><font color="#3973DE"
size="4" face="Times New Roman"> </font><font
color=red>定制串行化</font></b></p>
<p><font > 前面編輯器的例子使用</font><font face="Times New Roman">CString</font><font >類的字符串來保存文本行,由于它是</font><font face="Times New Roman">MFC</font><font >類,因此可以串行化自己,將自己寫入磁盤或從磁盤文件中讀取二進(jìn)制數(shù)據(jù)來建立對象。那么,如果不是標(biāo)準(zhǔn)的</font><font face="Times New Roman">MFC</font><font >類,比如用戶自己定義的類,如何讓它支持串行化呢?下面,我們結(jié)合前面第五章提到的就業(yè)調(diào)查表的例子來演示如何讓用戶定義的類支持串行化功能。</font></p>
<p><font > 要讓用戶定義的類支持串行化,一般分為五步:</font></p>
<p><font face="Times New Roman">1.</font><font >從</font><font face="Times New Roman">CObject</font><font >或其派生類派生出用戶的類</font></p>
<p><font face="Times New Roman">2.</font><font >重載</font><font
face="Times New Roman">Serialize()</font><font >成員函數(shù),加入必要的代碼,用以保存對象的數(shù)據(jù)成員到</font><font face="Times New Roman">CArchive</font><font >對象以及從</font><font
face="Times New Roman">CArchive</font><font >對象載入對象的數(shù)據(jù)成員狀態(tài)。</font></p>
<p><font face="Times New Roman">3.</font><font >在類聲明文件中,加入</font><font face="Times New Roman">DECLARE_SERIAL</font><font >宏。編譯時,編譯器將擴(kuò)充該宏,這是串行化對象所必需的。</font></p>
<p><font face="Times New Roman">4.</font><font >定義一個不帶參數(shù)的構(gòu)造函數(shù)。</font></p>
<p><font face="Times New Roman">5.</font><font >在實(shí)現(xiàn)文件中加入</font><font
face="Times New Roman">IMPLEMENT_SERIAL</font><font >宏。</font></p>
<p><font face="Times New Roman">class
CRegister:public CObject</font></p>
<p><font face="Times New Roman">{</font></p>
<blockquote>
<p><font size="2" face="Courier New">public:</font></p>
</blockquote>
<p><font size="2" face="Courier New">DECLARE_SERIAL(
CRegister)</font></p>
<p><font face="Courier New">//</font><font >必需提供一個不帶任何參數(shù)的空的構(gòu)造函數(shù)</font></p>
<blockquote>
<p><font size="2" face="Courier New">CRegister(){};</font></p>
</blockquote>
<p><font face="Times New Roman">public:</font></p>
<p><font face="Times New Roman">CString
strIncome;</font></p>
<p><font face="Times New Roman">CString strKind;</font></p>
<p><font face="Times New Roman">BOOL bMarried;</font></p>
<p><font face="Times New Roman">CString strName;</font></p>
<p><font face="Times New Roman">int nSex;</font></p>
<p><font face="Times New Roman">CString strUnit;</font></p>
<p><font face="Times New Roman">int nWork;</font></p>
<p><font face="Times New Roman">UINT nAge;</font></p>
<p><font face="Times New Roman">void
Serialize(CArchive&);</font></p>
<p><font face="Times New Roman">};</font></p>
<p><font face="Times New Roman"> MFC</font><font >在從磁盤文件載入對象狀態(tài)并重建對象時,需要有一個缺省的不帶任何參數(shù)的構(gòu)造函數(shù)。串行化對象將用該構(gòu)造函數(shù)生成一個對象,然后調(diào)用</font><font face="Times New Roman">Serialize()</font><font >函數(shù),用重建對象所需的值來填充對象的所有數(shù)據(jù)成員變量。</font></p>
<p><font > 構(gòu)造函數(shù)可以聲明為</font><font face="Times New Roman">public</font><font >、</font><font face="Times New Roman">protected</font><font >或</font><font face="Times New Roman">private</font><font >。如果使它成為</font><font
face="Times New Roman">protect</font><font >或</font><font face="Times New Roman">private</font><font >,則可以確保它只被串行化過程所使用。</font></p>
<p><font > 在類定義文件中給出</font><font face="Times New Roman">Serialize()</font><font >的定義。它包括對象的保存和載入兩部分。前面已經(jīng)提到,</font><font face="Times New Roman">CArchive</font><font >類提供一個</font><font
face="Times New Roman">IsStoring()</font><font >成員函數(shù)指示是保存數(shù)據(jù)到磁盤文件還是從磁盤文件載入對象。</font></p>
<p><font face="Times New Roman">void
CRegister::Serialize(CArchive& ar)</font></p>
<p><font face="Times New Roman">{</font></p>
<p><font face="Courier New">//</font><font >首先調(diào)用基類的</font><font
face="Courier New">Serialize()</font><font >方法。</font></p>
<p><font size="2" face="Courier New">CObject::Serialize(
ar);</font></p>
<p><font face="Times New Roman">if(ar.IsStoring())</font></p>
<p><font face="Times New Roman">{</font></p>
<p><font face="Times New Roman">ar<<strIncome;</font></p>
<p><font face="Times New Roman">ar<<strKind;</font></p>
<p><font face="Times New Roman">ar<<(int)bMarried;</font></p>
<p><font face="Times New Roman">ar<<strName;</font></p>
<p><font face="Times New Roman">ar<<nSez;</font></p>
<p><font face="Times New Roman">ar<<strUnit;</font></p>
<p><font face="Times New Roman">ar<<nWork;</font></p>
<p><font face="Times New Roman">ar<<(WORD)nAge;</font></p>
<p><font face="Times New Roman">}</font></p>
<p><font face="Times New Roman">else</font></p>
<p><font face="Times New Roman">{</font></p>
<p><font face="Times New Roman">ar>>strIncome;</font></p>
<p><font face="Times New Roman">ar>>strKind;</font></p>
<p><font face="Times New Roman">ar>>(int)bMarried;</font></p>
<p><font face="Times New Roman">ar>>strName;</font></p>
<p><font face="Times New Roman">ar>>nSex;</font></p>
<p><font face="Times New Roman">ar>>strUnit;</font></p>
<p><font face="Times New Roman">ar>>nWork;</font></p>
<p><font face="Times New Roman">ar>>(WORD)nAge;</font></p>
<p><font face="Times New Roman">}</font></p>
<p><font face="Times New Roman">}</font></p>
<p><font > 我們看到,對象的串行化實(shí)際上是通過調(diào)用對象中的數(shù)據(jù)成員的串行化來完成的。</font></p>
<div align="center"><center><table border="2"
cellpadding="2" cellspacing="0" width="100%"
bgcolor="#80D6FF">
<tr>
<td width="100%"><font >注意</font><font face="Times New Roman">:CArchive</font><font >類的</font><font
face="Times New Roman">>></font><font >和</font><font
face="Times New Roman"><<</font><font >操作符并不支持所有的標(biāo)準(zhǔn)數(shù)據(jù)類型。它支持的數(shù)據(jù)類型有:</font><font face="Times New Roman">CObject</font><font >、</font><font
face="Times New Roman">BYTE</font><font >、</font><font face="Times New Roman">WORD</font><font >、</font><font
face="Times New Roman">int</font><font >、</font><font face="Times New Roman">LONG</font><font >、</font><font
face="Times New Roman">DWORD</font><font >、</font><font face="Times New Roman">float</font><font >和</font><font
face="Times New Roman">double</font><font >。其他的類型的數(shù)據(jù)要進(jìn)行串行化輸入輸出時,需要將該類型的數(shù)據(jù)轉(zhuǎn)化為上述幾種類型之一方可。</font></td>
</tr>
</table>
</center></div>
<p><font ><br>
另外,在類的實(shí)現(xiàn)(類定義)文件開始處,還要加入</font><font face="Times New Roman">IMPLEMENT_SERIAL</font><font >宏。</font></p>
<blockquote>
<p><font face="Times New Roman">IMPLEMENT_SERIAL(
CRegister, CObject, 1 )</font></p>
</blockquote>
<p><font face="Times New Roman"> IMPLEMENT_SERIAL</font><font >宏用于定義一個從</font><font
face="Times New Roman">CObject</font><font >派生的可串行化類的各種函數(shù)。宏的第一和第二個參數(shù)分別代表可串行化的類名和該類的直接基類。</font></p>
<p><font > 第三個參數(shù)是對象的版本號,它是一個大于或等于零的整數(shù)。</font><font face="Times New Roman">MFC</font><font >串行化代碼在將對象讀入內(nèi)存時檢查版本號。如果磁盤文件上的對象的版本號和內(nèi)存中的對象的版本號不一致,</font><font face="Times New Roman">MFC</font><font >將拋出一個</font><font face="Times New Roman">CArchiveException</font><font >異常,阻止程序讀入一個不匹配版本的對象。</font></p>
<p><font > 現(xiàn)在,我們就可以象使用標(biāo)準(zhǔn)</font><font face="Times New Roman">MFC</font><font >類一樣使用</font><font face="Times New Roman">CRegister</font><font >的串行化功能了。</font></p>
<p><font face="Times New Roman">CArchive ar;</font></p>
<p><font face="Times New Roman">CRegister
reg1,reg2;</font></p>
<p><font face="Times New Roman">ar<<reg1<<reg2;</font></p>
<p><font > 讀者請?jiān)囍诘谖逭侣毠ふ{(diào)查表程序基礎(chǔ)上,增加保存調(diào)查信息到文件以及從文件中讀入調(diào)查表信息功能。對于多個調(diào)查表,可考慮采用</font><font face="Times New Roman">CObjList</font><font >鏈表保存多個對象的指針。</font></p>
<p><font > 串行化簡化了對象的保存和載入,為對象提供了持續(xù)性。但是,串行化本身還是具有一定的局限性的。串行化一次從文件中載入所有對象,這不適合于大文件編輯器和數(shù)據(jù)庫。對于數(shù)據(jù)庫和大文件編輯器,它們每次只是從文件中讀入一部分。此時,就要避開文檔的串行化機(jī)制來直接讀取和保存文件了。另外,使用外部文件格式(預(yù)先定義的文件格式而不是本應(yīng)用程序定義的文件格式)的程序一般也不使用文檔的串行化。下面我們就給出這樣一個例子,說明在不使用串行化情況下如何讀取和保存文件。</font></p>
<div align="center"><center><table border="0"
cellpadding="0" cellspacing="0" width="615">
<tr>
<td><a href="chap7_3.htm">上一頁</a></td>
<td><p align="right"><a href="chap7_5.htm">下一頁</a></p>
</td>
</tr>
</table>
</center></div><hr size="1" noshade color="#3973DE">
<p align="center"><font color="#000000" size="2">本教程由</font><a
href="http://vcdynasty.yeah.net"><font color="#000000"
size="2">Visual C++王朝(Where programmers come
together)</font></a><font color="#000000" size="2">協(xié)助制作<br>
未經(jīng)許可,請勿以任何形式復(fù)制</font></p>
</td>
</tr>
</table>
</center></div>
<p align="center"><font size="5"></font> </p>
<p><font ><b></b></font> </p>
<p><font ></font> </p>
<p> </p>
</body>
</html>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -