精華區beta CompBook 關於我們 聯絡資訊
作者: jjhou (jjhou) 標題: 【C++ 的沉迷與愛戀】 時間: Mon Sep 28 16:00:19 1998 【C++ 的沉迷與愛戀】 侯捷 jjhou@ccca.nctu.edu.tw 1998.09.28 第一次發表於 清大 BBS.楓橋驛站.電腦書訊版(140.114.87.5) 平面發表於 RunPC 雜誌 1998/11 月號(預定) ----------------------------------------------------------- 每年的 09/28 於我都是一個特殊的日子 -- 不只是因為教師節。今年 很特殊地沒有普天同慶,那麼我就寫篇文章自己慶祝一下好了。 根據我個人的過往、我的教學經驗、以及與週遭朋友的心得交流, 我對於 C++/OOP 的學習概況累積了相當多的想法。寫下這篇文章, 以為後學者戒。 ●<多型與虛擬> 序言節錄 首先讓我節錄 <多型與虛擬> 一書序言: ------------------------------------------------------------↓ <多型與虛擬> 序 (侯俊傑/松崗/1998/07) ..... 一般而言,C++ 是一個難學易用的語言。 C++ 的難學,初始在於其重重的佈幕,佈幕之中編譯器對我們的程式碼 做了太多的手腳,使我們慣於循序思考的工程腦袋一無所措。及長,又 面臨新的思維模式,使我們必須扭轉慣常的思考習慣。 C++ 的易用則在於其巨大的彈性,能夠以多型(polymorphism)、虛擬 (virtual)、模板(template)等種種方式,讓既有的碼去處理未知的 、未來的資料型態。 當然,易用必須先能用。用不好或不能用的話,「寫 C++ 程式」最後就 成了只是「使用 C++ 編譯器」,這是大家常拿來彼此調侃的笑話。 在「難學」的背景下,「易用」是使我們依然前仆後繼的動力。愈來愈 多的大學資訊科系把 C++ 開在大一課程,這雖然說明 C++ 是多麼地重 要,可也苦了資訊新兵們。 其實「難學」的最大癥結在於,很難得有一本書,能夠一針見血地指出 多型與虛擬的重要性;在我們粗具語法基礎之後,直接把我們導引到最 核心最重要的思想,並且在建立這個思想的過程中,提供足夠的必要基 礎。 ..... -------------------------------------------------------------↑ ●困難度之一 「C++ 是個難學易用的語言」,這句話相信很多人心有戚戚。C++ 的學 習難度,一在於語言本身太多的「幕」,一在於 "paradigm shift" (思考模式的移轉)。 傳統循序語言如 C, Pascal, Basic, Fortran...,除了模樣看起來稍有 不同,基本上都是函式 call 來 call 去,大同小異,很容易掌握。你 想做的動作,在 code 中都看得一清二楚。你所看不到的,犖犖大者也 不過就是編譯器為你的 function 加上處理堆疊所需的一小段碼(prologue 和 epilogue),這一小段碼基本上做的是 housekeeping 工作,你沒看 到也沒有關係(更好),並不影響你的程式邏輯。 C++ 不一樣,C++ 有太多和程式邏輯息息相關的動作是編譯器為我們加上 去的。換句話說 C++ 編譯器為我們「加碼」。如果不識清這一節,學習 C++ 有如霧裡看花,霧非霧,花非花。 編譯器為我們的 C++ 程式加了什麼碼呢?多了!物件誕生時 ctor 會被 喚起,物件死亡時 dtor 會被喚起,這都是加碼的結果。ctor 中設定 vtpr 和 vtbl,這也是加碼的結果。new 一個物件時會產生 memory block cookie,new 一個物件陣列時會有內部結構記錄 object size 和 class ctor...,這也都是佈幕後的工作。可以說,程式碼中看不到而卻必須完成 的所有與程式邏輯有關的動作,統統都是 C++ 編譯器加碼後的結果。 當繼承發生,整個情況變得稍微複雜起來。多重繼承又更複雜,虛擬繼承 再更複雜。 這些佈幕下的主題,統可歸類為所謂的 C++ object model。如果你不知 道這些底層機制,你就只能夠把 "make destructors virtual in base classes"(<Effective C++>, item14)或 "never treat arrays polymorphically" (<More Effective C++>, item 3)這類規則背下來,卻不明白它的道理。 用一樣東西,卻不明白它的道理,林語堂如是說:『不高明』。只知道 how,不知道 why,侯捷如是說:『不高明』。 ●困難度之二 C++ 的第二個學習難度,在於 "paradigm shift"(思考模式的移轉)。 別說自己設計 classes 了,光使用別人的 classes,就都是一種思考模 式和行為模式的移轉 -- MFC (or OWL) programmer 必然甚能夠領略並 體會我的意思。 前面所說的 C++ Object Model,偏屬程式設計的低層面;思考模式的 移轉,則是程式設計的高層面。能夠把物件導向(OO)威力發揮得最 淋漓盡致的,就是 polymorphism(多型)和 template(模板)。如果 你沒有使用這兩項特性,你根本就沒有踏入 OO 領域。 ●反覆焠鍊,循環震盪 想像 C++ 是一把用來解決程式問題的刀,要它堅軔,要它鋒利,就必 須經過多次的回火,在高熱和驟冷之間焠鍊。 初學 C++ 語法(syntax)之後,你應該儘快嘗試體驗 polymorphism (大致而言也就是 virtual functions 的應用)。等到對 OO 的精神 有了大局掌控的能力,但對 C++ 的許多小細節不甚清楚,就是回到 object model 焠鍊的時機。 成長,是在高階(polymorphism)和低階(object model)之間反覆 震盪,才能夠震盪到更高的位階,而不是平平庸庸於中階(C++ syntax) 的一灘死水。 ●不要沉淪於 C++ syntax 100 個人跟我說他懂 C++/OOP,只有 10% 不到可以讓我認為他沒有 胡吹大氣。太多的人,上嘛上不到 polymorphism,下嘛又下不到 object model。就這樣不上不下地卡在 C++ 語法層面。大一學了 C++,到大四快畢業了,連 virtual functions 是怎麼回事都期期 艾艾支支吾吾說不出個道理。 有時候我覺得,太苛責同學也於心不忍,因為同學們事實上處於一種 無知的狀態,既不知道 C++/OOP 該怎麼學,也不知道哪些書可以教他 們那麼學。所以,苛責同學,不如責怪老師。 眾所週知,大學教授泰半是動口不動手,普遍的心態是「論文第一, 升等為要;程式語言?哎,末流!」。「末流」課程通常由教授們輪流 教,誰倒楣誰教。於是就常常有「下學期要教 C++ 語言了,這學期 寒(暑)假趕快去要本書來 KK」的情況發生。偏偏程式語言這東西, 只動口不管用,一定要動手,而且要常動手。老師自己沒有摸到 C++/OOP 的精神,學生又能學到什麼? 有些學校資訊系聽說不教特定的程式語言,系上的態度是「語言是一 種自己學就好了的東西嘛,拿到大學殿堂來,哎,不入流」!循序性 (sequential)語言我認為尚有自修學會的可能,物件導向語言嘛, 以大學生的程度來講,自修實在困難,只會修出個四不像、半瓶水。 管不到學校!管不到教授!自求多福的情況下,希望看到這篇文章的 你,知道 C++/OOP 該怎麼學。 ●不要沉迷於 C++ semantics 對於底層知識感興趣的朋友,下探到 object model 領域,一定會非 常開心地在 object size、object layout、vptr/vtbl、以及許多佈 幕後的技術之間玩將起來。瞭解這些東西,當然是必要的,但是由於 一探究竟得其奧秘的快感與成就感,使得一些朋友們在這個層面裡 「玩」起來了,小地方玩得很精,玩得不亦樂乎,玩得忽略了 C++/OOP 的最終目標。 最終目標是 polymorphism! 我要說,在 C++ syntax 以及相對低階的 C++ semantics 裡,不要玩 得太過火。過猶不及,會傷身的。C++ 經典名書內附的一些習題,在我 看來頗有點玩得過火的味道。至於什麼百題精選、題庫大成,都滿無趣 的東西。Programming 應該是一種天馬行空的想像力與創意的組合; 如果你能夠自己想題目,譬如說實作一個天體運行的 class 體系、或是 實作一個生物分類(界門綱目科屬種)體系,不是很有趣嗎?準備資料 的過程中,查查百科全書,你也因此查到了太陽系九大行星的幾何資料, 哈雷慧星的軌道週期,或是黑面琵鷺的「界門綱目科屬種」英文名稱, 這難道不比鑽研於 ++++i 或 ----i 或 *&*&p 之類的頭腦體操題目有趣嗎? (看過不少這類好笑題目,沒一個記下來,只好胡亂寫幾個運算式。諸位 應該知道我說的那種頭腦體操題目) 固然,在科學與工程的領域裡頭,無技術無以為立,但別把自己弄得 過於僵化,過於匠氣。僵化與匠氣是我們教育體系的最大沉痾。到了高 專層次,敗象顯露無遺。 ●名書推薦 如果沒有介紹幾本好書,我就是為德不卒。 讓我再節錄 <多型與虛擬> 的二刷感言: ------------------------------------------------------------↓ <多型與虛擬> 一版二刷感言 (侯俊傑/松崗/1998/08) ..... C++ 相關書籍,如天上繁星,如過江之鯽。廣博如四庫全書者有之 (如 The C++ Programming Language、C++ Primer), 深奧宛如山重水複有之(如 Inside The C++ Object Model), 獨沽一味者有之(如 C++ Programming Style、More Effective C++), 獨樹一幟者有之(如 The Design and Evolution of C++), 另闢蹊徑者亦有之(如 STL tutorial Reference Guide)。 ..... --------------------------------------------------------------↑ 以下是我認為你應該要擁有的書籍。有趣的是,我才在自己班上做了一個 調查,擁有以下 1~5 本書的人舉手。舉手人數都很少,而且老是那幾位 (最高記錄是擁有四本)。這讓我感覺,強者恆強,弱者恆弱。悲夫! 1. C++ Primer (3/e), Lippman/A.W./1998 (聽說將有中譯本) 2. The C++ Programming Language (3/e), Bjarne/A.W./1997 (聽說 1999 會有中譯本) 這兩本書是 C++ 經典百科。就內容水平而言,我認為同為瑜亮。大多 數讀者的一般印象是,第一本較易接受,第二本澀味稍重。第二本書 作者 Bjarne 是 C++ 語言的創造者,所以有其權威性。我認識的多 位 C++/OO 高手,都是兩書齊具。 3. Inside The C++ Object Model, Lippman/A.W./1996 (中譯本 <深度探索 C++ 物件模型>) 全書講解 C++ object model,上窮碧落下黃泉。內容很好,層次也高, 只可惜原文書大大小小的錯誤繁如晨星,閱讀時需小心。 4. Effective C++, Meyers/A.W./1992 (印象似有中譯本,名稱忘了,誰可補充說明?) 5. More Effective C++, Meyers/A.W./1996 (有中譯本嗎?我不知道,誰可補充說明?) 同一作者的這兩本書,專講 C++ programming 的重要觀念,使你的程式 更穩健更有效率。書中許多觀念涉及 C++ object model,與 3. 混合看, 如魚得水。 6. Polymorphism in C++ <多型與虛擬> 侯俊傑/松崗/1998 (沒有中譯本 -- 它本身就是中文書) 在語法粗具的基礎上,直接把讀者導引到最核心最重要的思想,並且 在建立這個思想的過程中,提供足夠的必要基礎。 我只列出一本中文書,是因為這方面的中文書我看得少,英文書看得多。 「恐有遺珠之憾」這類「八方得體」的話,還是說一下好了 :)。 --- end  -- ※ Origin: 楓橋驛站<bbs.cs.nthu.edu.tw> ◆ Mail: jjhou@CCCA.NCTU.edu.tw ※ X-Info: Mave -> ric.bbs@ptt.csie.ntu.edu.tw ※ X-Sign: 0ROABLHPHZsCSVTVkCdU (99/07/09 7:05:21 )