深入浅出MFC第2版(PDF格式)-第171部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
這是這個主睿接懙念}目。
( )和 。把份 寫入檔案
4。 Runtime Type Information RTTI Dynamic Creation document
之,連同類別名稱和成員變數的值,洠в袉栴}。是的,點問睿矝'有,但是讀出
869
…………………………………………………………Page 932……………………………………………………………
第五篇 附錄
來就有問睿耍驗槟悴豢赡茏x個類別名稱到個字串然後對這個字串做 new
動作。「從檔案讀出類別名稱然後產生其物件」,就是 〃dynamic creation〃 的具體表
現。C++ 不支援這項能力,但 MFC 非要不可,因為有太多時候需要 dynamic
。其實你只要使用笨方法如,就可以解決 的問睿骸
creation dynamic creation
// pseudo code
read ClassName to str
if (str == 〃Class1〃)
new Class1;
else if (str == 〃Class2〃)
new Class2;
else if (str == 〃Class3〃)
new Class3;
else if (str == 〃Class4〃)
new Class4;
! K
MFC 小組比我們聰明嗎?不會。但是他們比我們懂得包裝。他們在MFC framework
架構起個由所有類別相關資訊(包括類別名稱及建構函式)組成的類別型錄網絡
(個串列),然後把類別名稱的比對動作埋藏在 虛擬函式。類別型錄
Serialize
網絡的每個成員就是 CRuntimeClass 物件,網絡的組成則是藉由類別宣告時的
DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE 巨 集 完 成 。
RUNTIME_CLASS 巨集就是取出「類別型錄網絡」的個元素(代表個類別)。
所以,當你的程式開始執行,整個 MFC 的絕大部份類別,都已經放在這個「類別
型錄網絡」之(噢,是的,當然也耗用了你的記憶體)。有了這網絡,RTTI (執行
時期型別辨識)和 Dynamic Creation 都不是問睿!
5。 Persistence 。文件內容要用什麼型式寫到檔案去,才能夠再從檔案讀出來恢復為個
個的物件?這就是 ( 稱之為 )要探討的睿俊1緯选
persistence MFC serialization
Serialize 虛擬函式的內部行為全部挖掘出來,並且實際觀察個文件檔的 hex 傾印
內容。
這五個部份是本書最精華的方,也是它獨步全球的方。要有這麼深入的了解,非得
觀察 MFC 原始碼不可。本書把相關的 MFC 碼整理出來,加相當多的示意圖,MFC
870
…………………………………………………………Page 933……………………………………………………………
附錄A 無責任書評
Internals 雖然挖得更廣,整理的功夫卻洠в羞@本好。
這本書用詞相當精準。用詞精準在容易岐路的物件導向領域至為重要,許多細微的觀
念就在字句推敲成形。
實例方面,希望看到琳琅滿目的範例程式的讀者,將會大失所望。這本書使用Visual C++
的標準範例 Scribble 。只有13~16 章才有幾個作者自己設計的程式,而且教育價值雖有,
實在有點其貌不揚。然而以Scribble 為範例主軸,有個意想不到的好處:常看 Microsoft
Systems Journal 或 Windows Developer's Journal 的朋友就知道,許多作家喜歡在示範新
技術或新構想時,以 Scribble 為載具。如果你對Scribble 十分熟悉,閱讀那些文章可就
瘢p就熟了。
本書的許多精心插圖,是令驚喜的方。圖解千言萬語,在這裡獲得最佳裕_。
871
…………………………………………………………Page 934……………………………………………………………
第五篇 附錄
鍋湯,要放多少沤泻茫坑邢矚g重口味,有雅好清如水。
本程式設計書籍,究竟要放多少碼,才能夠雅俗共賞,點頭?
關於這點,有兩種完全迥異的看法。第種看法似乎頗佔風,他們說書籍應該是解
釋程式的邏輯,程式的意念,程式設計的 呃 境界。因此出現在書的碼應該只能是
。。。 。。。
小小的、片段的、簡捷的。但凡有大落大落的碼出現,那便是不入流、難登大雅之
堂。我看過好多書評對於那種有著許多程式碼的書明嘲暗諷,甚而大加撻伐(呵呵,外
文期刊的書評很毒的)。
如果程式碼用來充篇幅,那就罵得好。
如果完整的碼用來給予完整的面觀,我就認為值得。
其實,程式碼是贅餘還是適得其所,完全視讀者的個情況而定。
Scribble 範例程式從第4章的 Step0 出發之後,陸陸續續只有片片斷斷的個個函式
碼。我認為有必要把本書所涵蓋的最後個版本 Step5 的完整原始碼列出,以為 Step0
之比對。
它來了。
抱怨程式碼太多的,可能是認為頁數多寡會反應在書籍售價。有些書是這樣。但這
本書,真的,我說,1000 頁或700 頁,都不會影響它的價格(與價值)。
872
…………………………………………………………Page 935……………………………………………………………
附錄B Scribble Step5 完整原始碼
附錄B
Scribble Step 5
完整原始碼
Scribble Step 5 是個擁有如功能的 MDI 塗鴉程式:
選單 利用滑鼠做塗鴉動作,
工具列 繪圖內容可存檔,亦可自檔案讀出。
子視窗縮小為圖示 同份 Document 開啟兩個 View 視窗 狀態列 分裂視窗
873
…………………………………………………………Page 936……………………………………………………………
第五篇 附錄
對話盒可設定繪筆粗細
列印與預樱А №撌住 ”眍^ Document 內容
SCRIBBLE。H
#0001 #ifndef __AFXWIN_H__
#0002 #error include 'stdafx。h' before including this file for PCH
#0003 #endif
#0004
#0005 #include 〃resource。h〃 // main symbols
#0006
#0007 /////////////////////////////////////////////////////////////////
#0008 // CScribbleApp:
874
…………………………………………………………Page 937……………………………………………………………
附錄B Scribble Step5 完整原始碼
#0009 // See Scribble。cpp for the implementation of this class
#0010 //
#0011
#0012 class CScribbleApp : public CWinApp
#0013 {
#0014 public:
#0015 CScribbleApp();
#0016
#0017 // Overrides
#0018 // ClassWizard generated virtual function overrides
#0019 //{{AFX_VIRTUAL(CScribbleApp)
#0020 public:
#0021 virtual BOOL InitInstance();
#0022 //}}AFX_VIRTUAL
#0023
#0024 // Implementation
#0025
#0026 //{{AFX_MSG(CScribbleApp)
#0027 afx_msg void OnAppAbout();
#0028 // NOTE the ClassWizard will add and remove member functions here。
#0029 // DO NOT EDIT what you see in these blocks of generated code !
#0030 //}}AFX_MSG
#0031 DECLARE_MESSAGE_MAP()
#0032 };
SCRIBBLE。CPP
#0001 #include 〃stdafx。h〃
#0002 #include 〃Scribble。h〃
#0003
#0004 #include 〃MainFrm。h〃
#0005 #include 〃ChildFrm。h〃
#0006 #include 〃ScribDoc。h〃
#0007 #include 〃ScribVw。h〃
#0008
#0009 #ifdef _DEBUG
#0010 #define new DEBUG_NEW
#0011 #undef THIS_FILE
#0012 static char THIS_FILE'' = __FILE__;
#0013 #endif
#0014
#0015 /////////////////////////////////////////////////////////////////
#0016 // CScribbleApp
#0017
#0018 BEGIN_MESSAGE_MAP(CScribbleApp; CWinApp)
#0019 //{{AFX_MSG_MAP(CScribbleApp)
875
…………………………………………………………Page 938……………………………………………………………
第五篇 附錄
#0020 ON_MAND(ID_APP_ABOUT; OnAppAbout)
#0021 // NOTE the ClassWizard will add and remove mapping macros here。
#0022 // DO NOT EDIT what you see in these blocks of generated code!
#0023 //}}AFX_MSG_MAP
#0024 // Standard file based document mands
#0025 ON_MAND(ID_FILE_NEW; CWinApp::OnFileNew)
#0026 ON_MAND(ID_FILE_OPEN; CWinApp::OnFileOpen)
#0027 // Standard print setup mand
#0028 ON_MAND(ID_FILE_PRINT_SETUP; CWinApp::OnFilePrintSetup)
#0029 END_MESSAGE_MAP()
#0030
#0031 /////////////////////////////////////////////////////////////////
#0032 // CScribbleApp construction
#0033
#0034 CScribbleApp::CScribbleApp()
#0035 {
#0036 // TODO: add construction code here;
#0037 // Place all significant initialization in InitInstance
#0038 }
#0039
#0040 //////////////////////////////////////////////////////////////
#0041 // The one and only CScribbleApp object
#0042
#0043 CScribbleApp theApp;
#0044