【無責任書評:拳拳到肉 擲地鏗鏘的三本 OOP 絕 …

看板CompBook作者時間24年前 (2000/06/15 10:46), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
【無責任書評:拳拳到肉 擲地鏗鏘的三本 OOP 絕佳小書】 侯捷 jjhou@ccca.nctu.edu.tw http://www.jjhou.com 本文將發表於 Run!PC 雜誌 2000/07,並整理於 侯捷網站/散文 2000 ---------------------------------------------------------------- 拿破崙雖然是個矮個子,一生叱吒卻儼然歷史的巨人。 今天我要介紹的三本書,雖然輕薄短小有如拿破崙的身材, 在 C++/OOP 領域裡,其份量與影響卻也有著拿破崙般的輝煌燦爛。 說它們輕薄短小,是的,讓數字說話:三本書合起來才 256+318+208=782 頁,只比 C++ 語言知名教本 C++ Primer 3/e 一半篇幅再多一些而已,比起 C++ 語言權威著作 The C++ Programming Language 3/e 也才達到三分之二的頁數份量。 逛書店時一個不留神,只怕你便遺漏了這些小書的存在。但如果你真 遺漏了它們的存在,實在是你的莫大損失。 就我個人的編程經驗,以及我的教學經驗(對象為業界工程師或 大學生),只要是 C++/OOP 設計思維與語言運用本身的問題, 非關 problem domain,百分之九十以上皆可在這三本書籍中找到 直接或間接的答案。這三本書是: ●Effective C++ 2/e : 50 Specific Ways to Improve Your Programs and Designs ●More Effective C++ : 35 New Ways to Improve Your Programs and Designs ●Exceptional C++ : 47 Engineering Puzzles, Programming Problems, and Solutions (註:前兩本書亦有 CD 產品(HTML 格式),以兩書合一的方式出售, 交叉索引甚為方便) 書名副標清楚告訴我們,這些書籍的特色就是以一個個的條款來 說明一些值得奉行或是必須避免的動作。以條款的方式進行,一方面 因為它們都不是 C++ 語言教本,而是更高層次的書籍,是給有語言基礎 (最好還有實際工作經驗)的人看的書,所以可以集中火力在特定主題上, 另一方面實乃因為條款型式可以強化主題,加深印象,提昇查閱檢索 的方便性與價值。 書中某些條款在 C++ 語言書籍裡或多或少也都有提到 — 雖然解釋 的深度可能不足。我舉個例子,Effective C++ 的條款13說 「Initialization list 中的 members 初始化排列次序應該和其在 class 內 的宣告次序相同」,C++ Primer 3/e 的 p721~p722 對此有相同意義的描述。 再舉個例子,Effective C++ 的條款14說 「總是讓 base class 擁有 virtual destructor」,這在 C++ Primer 3/e 的 p933 亦有相同意義的描述。諸如此類,不勝枚舉。但你是不是感覺, 那些金科玉律被淹沒在語言百科型書籍的細節叢林之中! 每一條準則都簡短、明確、容易記憶,可以確實提昇你的軟體效能。 每一條準則都是經驗豐富的 C++ 程式員的心血結晶,告訴你哪些是 幾乎總是需要奉行的動作,哪些是幾乎肯定要避免的事情。 某些條款甚至到達 patterns 的水準(註)。 註:所謂 patterns,在指程式設計過程中,開發人員常需 面對並解決的某些問題,被有系統地整理出解法,謂之 patterns (或譯為「樣式」)。Design Patterns 是此域中的經典書籍, 系統化地將可應用於眾多領域之 23 個基本 patterns 加以 分類整理。書中所提的 patterns 名稱,幾乎成為物件導向 設計領域的標準辭彙。 以上三本小書的功用不僅在提綱契領地點出重點,也在於對 每個主題有深刻的討論。在這些書籍中,你會發現一些忠告, 告訴你應該做些什麼,為什麼如此;也告訴你不應該做些什麼, 又為什麼如此。基本而言當然 whys 比 whats 更重要, 這便是這些書籍最有價值的地方。至於從速食的角度來看, 檢閱一系列準則,也比強記一或二本龐雜的教科書更輕鬆方便得多。 ---------------------------------------------------------- fig1 【基本資料】 書名:Effective C++ 2/e : 50 Specific Ways to Improve Your Programs and Designs 作者:Scott Meyers 出版:Addison Wesley, 0-201-92488-9, 1998 定價:US$ 37.95 頁數:256 Scott Meyers 的這本書籍,成名已久,同時也是此類書籍的濫觴。 這本書在 1992 年便有了第一版,我手上的第一版是 1996/12 的 第 12 刷。刷次原不能代表什麼,不過我在第二版的封底看到, 出版公司宣稱第一版銷售超過十萬本(不含各種譯本)。銷售量 能否代表什麼呢?銷售量低或許不一定能代表什麼,銷售量高則 相當程度地表示受到讀者的肯定。以此書訴求之技術層面而言, 這個銷售量是驚人的。(當然要是比起大陸某 C 語言書籍銷售 270 萬本,以及某 Visual Basic 書籍銷售破千萬本,那是小巫 見大巫了) 只要是在 C++ 領域裡打滾的程式員,馬上便可以從 Meyers 整理 出來的 50 個條款看出此書的價值。如果你拿 C++ 來討生活, 稍稍閱讀幾個條款的深度後,不掏腰包者幾稀。有些條款涉及的語意 層面較低,用以對容易出錯或混淆的數種程式寫法提出警告。另有 一些條款涉及的層次比較高,如第六章中對於各種繼承型式的討論、 以及 classes 之間除了繼承以外的其他關係的討論。至於條款E45 「知道 C++ 編譯器默默為我們完成和呼叫哪些函式」,以及 條款M24「瞭解 virtual functions、multiple inheritance、 virtual base classes、RTTI 所需的成本」,下涉物件模型與編譯器層面, 相當深入。套用我過去在「C++ 的沉迷與愛戀」一文中所用的辭, 此書在高熱和驟冷之間,在高階和低階之間焠鍊、循環、震盪。 本書第一頁列有它所獲得的讚譽。對於讀者,這是一份值得參考的資料, 我試著把它們譯為中文,條列於下: ※我必須真心地讚美 Meyers 的書,…這本書在記憶體管理架構 等主題上給予讀者卓越的引導,並對不同型式之 C++ 繼承機制 有極佳的解釋。 - New York Computerist ※在你開始著手第一個真正的 C++ 專案之前,你應該閱讀本書; 在你獲得一些實務經驗之後,你應該再讀一遍。 - comp.lang.c++ ※本書有一個子標題「改善你的程式技術與設計思維的 50 個 有效作法 」。作者不只提供你撰寫 C++ 碼時應該遵循的明白 規則,也提供了深入的解釋與範例。 - Sun Expert ※我慎重推薦 Effective C++ 給任何渴望在中高階層面精通 C++ 的人。 - The C User's Journal ※在各種寫給中高階程式員看的 C++ 書籍中,這是我所見過 最棒的一本。作者以一系列短文敘述 C++ 程式員遭遇的常見 問題。…本書既有趣又有用,在程式設計書籍中誠屬罕見。 - comp.lang.c++ ※本書在取材範圍和風味上類似另一本由 William Strunk 和 E.B. White 合著的小書 The Eements of Style;至少 二者在我的書架上距離不遠。…這是一本十分謹慎而適度的 小書,有著清楚的目標,並且完成了它們。 - C++ Report ※這本書內含對 C++ 開發工作的許多實用忠告。 - DEC Professional ※C++ 程式員不只應該擁有這本書,而且應該確實運用這本書。 書中的文字極易拿來實際運用。交叉參考與索引的功夫做得很好。 - Computer Language ※這是一本 193 頁的傑作。…我保證 50 個條款中必定有 某一些會攫取你的注意力並對你產生啟蒙作用,你的謹慎 投資將獲得回報。…這是一本文筆優越、真材實料的書籍, 目標瞄準重視流暢與效率的所有 C++ 程式員。 - Stan Kelley-Bootle, UNIX Review ※這本絕妙好書提供了 50 個招數,幫助我們把 C++ 運用得 更好。每一位 C++ 程式員桌上都應該有這一本書。…在 提昇 C++ 程式設計的整體品質上, Scott Meyers 這份 珍貴的禮物或許比業內任何人士的貢獻都大。』 -- Jesse Liberty, C++ Report 下面列出 Effective C++ 2/e 的各個條款(我試著譯為中文), 一方面讓這篇書評的實用性更高一些,一方面就讓這些條款標題 直接彰顯它們的價值吧。 第一章:改變舊有的 C 習慣 條款1:儘量以 const 和 inline 取代 #define 條款2:儘量以 <iostream> 取代 <stdio.h> 條款3:儘量以 new 和 delete 取代 malloc() 和 free() 條款4:儘量使用 C++ 風格的註解型式 第二章:記憶體管理(Memory Management) 條款5:使用相同型式的 new 和 delete 條款6:記得在 destructor 中以 delete 對付 pointer members 條款7:為記憶體不足的狀況預做準備 條款8:撰寫 operator new 和 operator delete 時應遵行公約 條款9:避免遮掩了 new 的正規型式 條款10:如果你寫了一個 operator new,請對應也寫一個 operator delete 第三章:建構式,解構式,和 Assignment 運算子 條款11:如果 classes 內動態配置有記憶體,請為此 class 宣告一個 copy constructor 和一個 assignment 運算子 條款12:在 constructor 中儘量以 initialization 取代 assignment 條款13:Initialization list 中的 members 初始化排列次序應該和其在 class 內的宣告 次序相同 條款14:總是讓 base class 擁有 virtual destructor 條款15:令 operator= 傳回「*this 的 reference」 條款16:在 operator= 中為所有的 data members 指派內容 條款17:在 operator= 中檢查是否「自己派給自己」 第四章:類別與函式之設計和宣告 條款18:努力讓介面完滿且最小化 條款19:區分 member functions, non-member functions 和 friend functions 三者 條款20:避免將 data members 放在公開介面中 條款21:儘可能使用 const 條款22:儘量使用 pass-by-reference(傳址),少用 pass-by-value(傳值) 條款23:當你必須傳回 object 時,不要嘗試傳回 reference 條款24:在函式多載化(function overloading)和參數預設化(parameter defaulting) 之間,謹慎抉擇 條款25:避免對指標型別和數值型別進行多載化 條款26:防衛潛伏的 ambiguity(模稜兩可)狀態 條款27:如果不想使用編譯器暗自產生的 member functions,就應該明白拒絕它 條款28:嘗試切割 global namespace(全域命名空間) 第五章:類別與函式之實作 條款29:避免傳回內部資料的 handles 條款30:避免寫出 member function,傳回一個 non-const pointer 或 reference 並以之 指向較低存取層級的 members 條款31:千萬不要傳回「函式內 local 物件的 reference」,或是「函式內以 new 獲得的 指標所指的物件」 條款32:儘可能延緩變數定義式的出現 條款33:明智地運用 inlining 條款34:將檔案之間的編譯依存關係(compilation dependencies)降至最低 第六章:繼承機制與物件導向設計 條款35:確定你的 public inheritance 模塑出 "isa" 的關係 條款36:區分「介面繼承(interface inheritance)」和「實作繼承(implementation inheritance)」 條款37:絕對不要重新定義一個繼承而來的非虛擬函式 條款38:絕對不要重新定義一個繼承而來的預設參數值 條款39:避免在繼承體系中做 cast down(向下轉型)的動作 條款40:透過 layering(分層技術)來模塑 has-a 或 is-implemented-in-terms-of 的關 係 條款41:區分 inheritance 和 templates 條款42:明智地運用 private inheritance(私有繼承) 條款43:明智地運用多重繼承(multiple inheritance,MI) 條款44:說出你的意思並瞭解你所說的每一句話 第七章:雜項討論(Miscellany) 條款45:知道 C++(編譯器)默默為我們完成和呼叫哪些函式 條款46:寧願編譯和聯結時出錯,也不要執行時才錯 條款47:使用 non-local static objects 之前先確定它已有初值 條款48:不要對編譯器的警告訊息視如不見 條款49:儘量讓自己熟悉 C++ 標準程式庫 條款50:加強自己對 C++ 的瞭解 ------------------------------------------------------------------- fig2 【基本資料】 書名:More Effective C++ : 35 New Ways to Improve Your Programs and Designs 作者:Scott Meyers 出版:Addison Wesley, 0-201-63371-X, 1996 定價:未標示 頁數:318 繼 Effective C++ 之後,Scott Meyers 於 1996 推出這本 「續集」。條款變得比較少,頁數倒是多了一些,原因是 這次選材比「第一集」更高階,尤其是第五章。Meyers 將 此章命名為技術(Techniques),並明白告訴你,其中都是 一些 patterns,例如 virtual ctors、smart pointers、 reference counting、proxy classes,double dispatching… 等等。這一章的每個條款篇幅都在 15~30 頁之譜,實在讓人有 「山窮水盡疑無路,柳暗花明又一村」之嘆。 雖然出版年代稍嫌久遠,本書並沒有第二版,原因是當其 出版之時(1996),C++ Standard 已經幾乎定案,本書 即依當時的標準草案而寫。其間與現今之 C++ 標準規格 幾乎相同。可能變化的幾個彈性之處,Meyers 也都有所 說明與提示。讀者可以連結作者提供的網址,看看上下兩集 的勘誤與討論(數量之多,令人驚恐。幸好多是技術討論 或文字斟酌,並沒有什麼重大誤失)。 本書第一頁列有它所獲得的讚譽。對於讀者,這是一份值得參考 的資料,我試著把它們譯為中文,條列於下: ※這是一本多方面發人深省的 C++ 書籍:不論在你偶爾用到的 語言特性上,或是在你自以為十分熟悉的語言特性上。只有深刻 瞭解 C++ 編譯器如何解釋你的碼,你才有可能以 C++ 語言寫出 穩健強固的軟體。本書是協助你獲得此等層級之瞭解過程中, 一份極具價值的資源。讀過本書之後,我P覺像是瀏覽了 C++ 程式大師所檢閱過的碼,並獲得許多極具價值的洞見。 - Fred Wild, Vce President of Technology, Advantage Software echnologies ※本書內含大量重要的技術,這些技術是撰寫優良 C++ 程式所 不可或缺的。本書解釋如何設計和實作這些觀念,以及潛伏在 其他某些替代方案中的陷阱。本書亦含晚近加入之 C++ 特性的 詳細說明。任何人如果想要好好地運用這些新特性,最好買一本 並且放在隨手可得之處,以備查閱。 - Chrisopher J. Van Wyk, Professor Mahematics and Computer Science, Drew University ※這是一本具備工業強度的最佳書籍。對於已經閱讀過 Effetive C++ 的人,這是完美的續集。 - Eric Nagler, ++ Instructor and Author, Univesity of California Santa Cruz Extension ※More Effective C++ 是一本無微不至而且價值不扉的書籍, 是 Scott 第一本書 Effective C++ 的續集。我相信每一位 專業的 C++ 軟體開發人員都應該讀過並記憶 Effective C++ 和 More Effective C++ 兩本書內的各種招式,以及其中重要 (並且有時候不可思議)的語言面向。我強烈推薦這兩本書給 軟體開發人員、測試人員、管理人員…,每個人都可以從 Scott 專家級的知識與卓越的表達能力中獲益。 - Steve Burkett, Software Consutant 以下列出 More Effective C++ 的各個條款(我試著譯為中文), 一方面讓這篇書評的實用性更高一些,一方面就讓這些條款標題 直接彰顯它們的價值吧。 第一章:基礎議題(Basics) 條款1:仔細區別 pointers 和 references 條款2:最好使用 C++ 轉型運算子 條款3:絕對不要以 polymorphically(多型)方式來處理陣列 條款4:非必要不使用 default constructor 第二章:運算子(Operators) 條款5:對自定的型別轉換函式保持警覺 條款6:區別 increment/decrement 運算子的前序(prefix)和後序(postfix)型式 條款7:千萬不要多載化 &&, ||, 和 , 運算子 條款8:瞭解各種不同意義的 new 和 delete 第三章:異常情況(Exceptions) 條款9:利用 destructors 避免遺失資源 條款10:在 constructors 內阻止資源的遺失(resource leaks) 條款11:禁止異常訊息(exceptions)流出 destructors 之外 條款12:瞭解「丟出一個 exception」與「傳遞一個參數」或「呼叫一個虛擬函式」之間的 差異 條款13:以 by reference 方式捕捉 exceptions 條款14:明智運用 exception specifications 條款15:瞭解異常處理(exception handling)的成本 第四章:效率(Efficiency) 條款16:謹記 80-20 法則 條款17:考慮使用 lazy evaluation 條款18:分期攤還預期的計算成本 條款19:瞭解暫時性物件的來源 條款20:協助完成「傳回值最佳化(RVO)」 條款21:利用多載化技術(overload)避免隱式型別轉換 條款22:考慮以運算子的複合型式(op=)取代其獨身型式(op) 條款23:考慮使用其他程式庫 條款24:瞭解 virtual functions、multiple inheritance、virtual base classes、 runtime type identification 所需的成本 第五章:技術(Techniques,又稱 Idioms 或 Pattern) 條款25:將 constructor 和 non-member functions 虛擬化 條款26:限制某個 class 所能產生的物件數量 條款27:要求(或禁止)物件產生於 heap 之中 條款28:Smart Pointers(精靈指標) 條款29:Reference counting(參用計數) 條款30:Proxy classes(替身類別、代理人類別) 條款31:讓函式根據一個以上的物件型別來決定如何虛擬化 第六章:雜項討論(Miscellany) 條款32:在未來時態下發展程式 條款33:將非尾端類別(non-leaf classes)設計為抽象類別(abstract classes) 條款34:如何在同一個程式中結合 C++ 和 C 條款35:讓自己習慣使用標準的 C++ 語言 ------------------------------------------------------------------- fig3 【基本資料】 書名:Exceptional C++ : 47 Engineering Puzzles, Programming Problems, and Solutions 作者:Herb Sutter 出版:Addison Wesley, 0-201-61562-2, 1999 定價:US$ 33.95 頁數:206 相較於前兩本威名遠播的老大哥,這本小書不但資歷淺,作者 也似乎不是那麼有名。真的不那麼有名嗎?未必,這要 看你熟悉哪個領域,在哪個領域活動而定。本書內容源自極受 歡迎的 C++ 網際網路節目 Guru of the Week,作者 Herb Sutter 正是這個網路節目的創辦者,同時也是 C++ Report 的專欄作家,以及網際網路討論群 comp.lang.c++.moderated 的創始主持人。 本書的一個最大特色是,以實例進行的方式,告訴你如何 以標準 C++ 進行軟體工程。書中所列的實例,有些是 棘手的 C++/OOP 疑難雜症,有些展示穩健強固且具擴充性的程式碼。 只需數分鐘時間,你便可以拿書中一些 C++ 設計問題和 實作問題來挑戰自己並且獲得樂趣(是的,每個問題都有一個難度評分)。 每一個實例,都可以測驗你的觀念正確與否。書中許多主題與 Effective C++ 和 More Effective C++ 的條款相互輝映, 一個實例之中可能隱含了 Meyers 兩本書的數個條款的運用。 順帶一提,這本書有老大哥 Scott Meyers 寫序推薦。 以下列出 Exceptional C++ 的各個條款(我試著譯為中文), Sutter 下標題的方式不像 Meyers 那麼具有實用性。不過, 這些標題大略呈現了本書的方向,所以,還是讓它們自我說明吧。 第一章:泛型程式設計與 C++ 標準程式庫 條款1:Iterators(泛型指標) 條款2:無分大小寫的字串 之一 條款3:無分大小寫的字串 之二 條款4:將泛型容器(Generic Containers)的重用性擴張至最大 之一 條款5:將泛型容器(Generic Containers)的重用性擴張至最大 之二 條款6:暫時物件 條款7:使用標準程式庫(再談暫時物件) 第二章:Exception-Safety(異常情況下仍然安全)的主題與相關技術 條款8: 撰寫 Exception-Safe 程式碼 之一 條款9: 撰寫 Exception-Safe 程式碼 之二 條款10:撰寫 Exception-Safe 程式碼 之三 條款11:撰寫 Exception-Safe 程式碼 之四 條款12:撰寫 Exception-Safe 程式碼 之五 條款13:撰寫 Exception-Safe 程式碼 之六 條款14:撰寫 Exception-Safe 程式碼 之七 條款15:撰寫 Exception-Safe 程式碼 之八 條款16:撰寫 Exception-Safe 程式碼 之九 條款17:撰寫 Exception-Safe 程式碼 之十 條款18:程式碼複雜度 之一 條款19:程式碼複雜度 之二 第三章:Class 的設計與繼承 條款20:Class 技術 條款21:改寫(Overriding)虛擬函式 條款22:Classes 之間的關係 之一 條款23:Classes 之間的關係 之二 條款24:使用/禁用 繼承(Inheritance) 條款25:物件導向程式設計 第四章:編譯器防火牆(Firewalls)及 Pimpl Idiom 條款26:將編譯時期的依存性最小化 之一 條款27:將編譯時期的依存性最小化 之二 條款28:將編譯時期的依存性最小化 之三 條款29:編譯防火牆(Compilation Firewalls) 條款30:The "Fast Pimpl" Idiom 第五章:名稱查詢(Name Lookup)、命名空間(Namespaes)、介面準則(Interface Principle) 條款31:名稱查詢與介面準則 之一 條款32:名稱查詢與介面準則 之二 條款33:名稱查詢與介面準則 之三 條款34:名稱查詢與介面準則 之四 第六章:記憶體管理 條款 35:記憶體管理 之一 條款 36:記憶體管理 之二 條款 37:auto_ptr 第七章:陷阱、易犯錯誤與反常作法 條款 38:物件識別(Object Identity) 條款 39:自動轉換(Automatic Conversions) 條款 40:物件壽命(Object Lifetimes)之一 條款 41:物件壽命(Object Lifetimes)之二 第八章:雜項主題 條款 42:變數的初始化 條款 43:常數性的正確性(Const-Correctness) 條款 44:轉型(Casts) 條款 45:真假值(bool) 條款 46:轉呼叫(Forwarding)函式 條款 47:控制流程(Control Flow) ●結語 理論與實務的結合,是每一位資訊從業人員希望達到的目標。 過多的照本宣科,過少的實務經驗(真正有價值的實務經驗), 卻是目前資訊相關書籍的普遍寫照。 Effective C++,More Effective C++, 和 Exceptional C++, 這三本書不僅在實務面上提出極為寶貴的準則,並以 豐富而紮實的理論基礎,深入解釋每一條準則背後的來龍去脈。 可以相當程度地提昇你的 C++ 程式技術與 OO 設計思維。 著名的語言專家 Benjamin Whorf 曾說:『語言可以塑造人類 思考的方式,並決定人類思考的內容』。使用 C++ 語言, 絕不僅只於使用 C++ 編譯器(很多人確是如此 — 雖然他們不自覺); 重要的是運用隱含於語意之中的物件導向(Object Oriented)觀念 與泛型(Genericity)觀念,在軟體設計階段便創造出一個 有彈性、易修改、適用未來時態的架構。 對於物件導向領域的生手,這三本書可以給你一個震憾教育, 讓你知道過去的寫作是多麼地不嚴謹、觀念是多麼地不成熟。 或許這套書會促使很多自以為是的讀者謙卑地認知自我的不足, 並謙卑地終於知道什麼是井蛙、河魚和燕雀。 至於物件導向箇中老手,是的,這三本書為你整理出多年打滾 所獲的寶貴心得,佐以深度的學理探討,必然讓你有相見恨晚之嘆。 -- the end  -- ※ Origin: 楓橋驛站<bbs.cs.nthu.edu.tw> ◆ Mail: jjhou@ccca.nctu.edu.tw
文章代碼(AID): #vI4EW00 (CompBook)