天啊,這本書竟是如此輕薄短小。我真想大叫一聲“哇歐”!C++ Primer加上索引、扉頁、謝詞之後,厚達1237頁,而此書卻只有薄薄276頁。套句拳擊術語,這是一部“輕量級”作品。
每個人都會好奇這究竟是怎麼回事。的確,這裡頭有一段故事。
過去數年來,我不斷纏著迪斯尼電影動畫公司(Disney FeatureAnimation)的每一個人,請求讓我親身參與一部電影的製作。我纏著導演,甚至Mickey本人(如果我可以說出來的話),要求一份管理工作。我會如此瘋狂,部分原因是深陷於好萊塢大屏幕那令人神往的無盡魔力而難以自拔。除了計算機科學方面的學位,我還擁有藝術碩士的頭銜,而電影工作似乎可以為我帶來個人專長的某種整合。我要求管理工作,為的是從製片過程中獲取經驗,以便提供實際有用的工具。身為一個C++編譯器編寫者,我一直都是自己最主要的用戶之一。而你知道,當你是自己軟件的主力抱怨者時,你就很難再為自己辯護或覺得受到不公平的責難。
《幻想曲2000》(Fantasia2000)片中有一段火鳥(Firebird)的特效鏡頭。其計算機特效指導對於我的加盟頗感興趣。不過,為了掂掂我的斤兩,他要求我先寫個工具,讀入為某段場景所攝的原始數據,再由此產生可嵌入Houdini動畫套件中的攝影機節點(cameranode)。當然,我用C++把它順利搞定了。他們愛死它了,我也因此得到了我夢寐以求的工作。
有一次,在製片過程中(在此特別感謝Jinko和Chyuan),我被要求以Perl重寫那個工具。其他的TD並非編程高手,僅僅知道Perl、Tcl之類的程序語言。(TD是電影界的術語,指的是技術導演。我是這部片子的軟件TD,我們還有一位燈光TD〔你好,Mira〕,一位模型TD〔你好,Tim〕,以及電影特效動畫師〔你好,Mike,Steve,Tonya〕。)而且,喔,天啊,我得趕著點,因為我們想要獲得一些觀念上的實證,而導演(你好,Paul和Gaetan)及特效總監(你好,Dave)正等著結果,準備呈給公司大頭目(你好,Peter)。這雖然不是什麼緊急要務,可是,你知道的……,唉。
這令我感到些許為難。我自信可以用C++快速完成,但我不懂Perl。好吧,我想,我去找本書抱抱佛腳好了——前提是這本書不能太厚,起碼此刻不能太厚。而且它最好不要告訴我太多東西,雖然我知道我應該知道每一樣東西,不過暫且等等吧。畢竟這只是一場表演:導演們需要一些經過證實的概念,藝術家需要一些東西協助證實其概念,而製片(你好,heck),她需要的是一天48小時。此刻我不需要全世界最棒的Perl大全,我需要的是一本能妥善引導我前進,使我不致偏離正軌過遠的小書。
我找到了Randal Schwartz的LearningPerl,它讓我立即上手並進展神速,而且頗具閱讀趣味。不過,就像其他有趣的計算機書籍一樣,它也略去了不少值得一讀的內容——儘管在那個時間點,我並不需要了解所有內容,我只需要讓我的Perl程序乖乖動起來。
我終於在感傷的心境中明白,C++ Primer第三版其實無法扮演人們在初學C++時的導師角色。它太龐大了。當然,我還是認為它是一本讓我驕傲的巨著——特別是由於邀請到JoséeLajoie共同完成。但是,對於想立刻學會C++程序語言的人來說,這本巨著實在過於龐大復雜。這正是本書的由來。
你或許會想,C++又不是Perl。完全正確!本書也非LearningPerl,它談的是如何學習C++。真正的問題在於,誰能夠在散盡千頁篇幅之後,猶敢自稱教導了所有的東西呢?
1.精細度。在計算機繪圖領域中,精細度指的是影像被描繪出來的鮮明程度。畫面左上角那位騎在馬背上的匈奴人,需要一張看得清楚眼睛的臉、頭髮、五點鐘方向的影子、衣服……。匈奴人的背後——不,不是那塊岩石,老天——唔,相較之下無關緊要。因此我們不會以相同的精細度來描繪這兩個影像。同樣道理,本書的精細度在相當程度上做了降低。依我看,C++Primer除了在運算符重載(operatoroverloading)方面的實例討論稍嫌不足外,可說極其完備了(我敢這麼說是因為Josée也有一份功勞)。但儘管如此,C++Primer還花了46頁篇幅討論操作符重載,並附上了範例,而本書卻僅以兩頁帶過。
2.語言核心。當我還是C++ Report的編輯時,我常說,雜誌編輯有一半工作花在決定哪些題材應該放入,哪些不要。這句話對本書一樣成立。本書內容是圍繞在編程過程中所發生的一系列問題組織的。我介紹編程語言本身的特性,藉此來為不同的問題提供解決之道。書中並未述及任何一個可由多繼承或虛繼承解決的問題,所以我也就完全沒有討論這兩個主題。然而,為了實現iteratorclass,我必須引入嵌套類型(nested type)。Class的類型轉換操作符很容易被錯用,解釋起來也很複雜,所以我不打算在書中提到它。諸如此類。我對題材的選擇以及對語言特性的呈現順序,歡迎大家指教批評。這是我的選擇,也是我的職責。
3.範例的數量。C++ Primer有數百頁代碼,鉅細糜遺,其中甚至包括一套面向對象的(ObjectOriented)文本檢索系統,以及十個左右的完整class。雖然本書也有代碼,但數量遠不及C++Primer。為了彌補這項缺憾,我將所有習題解答都置於附錄A。誠如我的編輯DeborahLafferty所言,“如果你想提高教學速度,唾手可得的解答對於學習的強化極有幫助。”
結構與組織
本書由七章和兩份附錄構成。第1章藉著撰寫一個具有互動性質的小程序,描繪C++語言預先定義的部分。這一章涵蓋了內置的數據類型、語言預定義的運算符(operator)、標準庫中的vector和string、條件語句和循環語句、輸入和輸出用的iostream庫。我之所以在本章介紹vector和string這兩個class,是因為我想鼓勵讀者多多利用它們取代語言內置的數組(array)和C-style字符串。
第2章解釋函數的設計與使用,並逐一查看C++函數的多種不同風貌,包括inline函數、重載(overloaded)函數、function template,以及函數指針(pointers to functions)。
第3章涵蓋了所謂的Standard TemplateLibrary(STL):一組容器類(包括vector、list、set、map,等等)、一組作用於容器上的泛型算法(包括sort()、copy() 、merge(),等等)。附錄B按字典順序列出了最廣為運用的泛型算法,並逐一附上了使用實例。
身為一個C++程序員,你的主要任務便是提交class以及面向對象的class層次體系。第4章將帶領你親身了解class機制的設計與使用過程。在這個過程中,你會看到如何為自身的應用系統建立起專屬的數據類型。第5章介紹如何擴展class,使多個相關的class形成族系,支持面向對象的class層次體系。以我在夢工廠動畫電影公司(DreamworksAnimation)擔任顧問的經驗為例,那時我們設計了一些class,用來進行四個頻道影像合成之類的工作。我們使用了繼承和動態綁定(dynamicbinding)技術,定義影像合成所需的class層次體系,而不只是設計八個獨立的class。
第6章的重頭戲是class template,那是建立class時的一種先行描述,讓我們得以將class用到的一個(或多個)數據類型或數據值,抽離並參數化。以vector為例,可能需要將其元素的類型加以參數化,而buffer的設計不僅得將元素類型參數化,還得將其緩衝區容量參數化。本章的行進路線圍繞在二分樹(binary tree)classtemplate的實現上。
最後一章,第7章,介紹如何使用C++的異常處理機制(exception handlingfacility),並示範如何將它融入標準庫所定義的異常體系中。附錄A是本書習題解答。附錄B提供了關於最廣為運用的一些泛型算法的相關討論與使用實例。
關於源代碼
本書的所有程序,以及習題解答中的完整代碼,都可從網上獲得。你可以在Addison Wesley Longman的網站(
www.awl.com/cseng/titles/0-201-48518-4)或我的個人首頁(
www.objectwrite.com)中取得。所有程序均在VisualC++ 5.0環境中以Intel C++編譯器測試過,也在Visual C++ 6.0環境中以MicrosoftC++編譯器測試過。你或許需要稍微修改一下代碼才能在自己的系統上編譯成功。如果你需要做一些修改並且做了,請將修改結果寄一份給我(
slippman@objectwrite.com),我會將它們附上你的大名,附於習題解答代碼中。請注意,本書並未顯現所有代碼。
致謝
在這裡,我要特別感謝C++ Primer第三版的共同作者JoséeLajoie。不僅因為她為本書初稿提供了許多深入見解,更因為她在背後不斷地給我鼓舞。我也要特別感謝Dave Slayton以他那犀利的綠色鉛筆,徹底審閱了文本內容與程序範例。Steve Vinoski則以同情但堅決的口吻,為本書初稿提供了許多寶貴意見。
特別感謝Addison-Wesley編輯團隊:全書編輯Deborah Lafferty從頭到尾支持這個項目;審稿編輯BestyHardinger對本書文字的可讀性貢獻最大;產品經理John Fuller帶領我們把一堆文稿化為一本完整的圖書。
撰寫本書的過程中,我同時還擔任獨立顧問工作,因此必須兼顧書稿和客戶。感謝我的客戶對我如此體諒和寬容。我要感謝ColinLipworth、Edwin Leonard、Kenneth Meyer,因為你們的耐心與信賴,本書才得以完成。
更多讀物
內舉不避親,我要推薦C++書籍中最好的兩本,那便是Lippman與Lajoie合著的C++Primer,以及Stroustrup的著作The C++ Programming Language。這兩本書目前均為第3版。我會在本書各主題內提供其他更深入的參考書目。以下是本書的參考書目。(你可以在C++ Primer和The C++Programming Language中找到更廣泛的參考文獻。)
[LIPPMAN98] Lip