?? 學習c++實踐者的方法.txt
字號:
4. 名字查找
5. 模板參數推導規則
6. 異常
7. OO(動態)和GP(靜態)兩種范式的應用場景和交互
總而言之,這一節的目的是要告訴你從一個較高的層次去把握C++中的復雜性。其中最重要的一個指導思想就是在學習的過程中注意你正學習的技術或細節到底是80%場景下的還是20%場景下的(一般來說,讀完兩本書——后面會提到——之后你就能夠很容易的對此進行判斷了),如果是20%場景下的(有大量這類復雜性,其中尤數各種各樣的workarounds為巨),那么也許最好的做法是只記住一個大概,不去作任何深究。此外,一般來說,不管使用哪門語言,認識語言陷阱對于編程來說都是一個必要的條件,語言陷阱的特點是如果你掉進去了,那么很大可能意味著你本來就不知道這有個陷阱,后者很大可能意味著你不知道如何解決。
學習C++:實踐者的方法
在上面寫了那么多之后,如何學習C++這個問題的答案其實已經很明顯了。我們所欠缺的是一個書單。
第一本
如果你是一個C++程序員,那么很大的可能性你會需要用到底層知識(硬件平臺架構、緩存、指令流水線、硬件優化、內存、整數&浮點數運算等);這是因為兩個主要原因:一,了解底層知識有助于寫出高效的代碼。二,C++這樣的接近硬件的語言為了降低語言抽象的效率懲罰,在語言設計上作了很多折衷,比如內建的有限精度整型和浮點型,比如指針。這就意味著,用這類語言編程容易掉進Joel所謂的“抽象漏洞”,需要你在語言提供的抽象層面之下去思考并解決遇到的問題,此時的底層知識便能幫上大忙。因此,一本從程序員(而不是電子工程師)的角度去介紹底層知識的書會非常有幫助——這就是推薦《Computer Systems:A Programmers Perspective》(以下簡稱CSAPP)(中譯本《深入理解計算機系統》)的原因。
第三本(是的,第三本)
另一方面,C++不同于C的一個關鍵地方就在于,C++在完全保留有C的高效的基礎上,增添了抽象機制。而所謂的“現代C++風格”便是倡導正確利用C++的抽象機制和這些機制構建出來的現代C++庫(以STL為代表)的,Bjarne也很早就倡導將C++當作一門不同于C的新語言來學習(就拿內存管理來說,使用現代C++的內存管理技術,幾乎可以完全避免new和delete),因此,一本從這個思路來介紹C++的入門書籍是非常必要的——這就是推薦《Accelerated C++》的原因(以下簡稱AC++)?!禔ccelerated C++》的作者Andrew Koenig是C++標準化過程中的核心人物之一。
第二本
C++是在C語言大行其道的歷史背景下發展起來的,在一開始以及后來的相當長一段時間內,C++是C的超集,所有C的特性在C++里面都有,因此導致了大量后來的C++入門書籍都從C講起,實際上,這是一個誤導,因為C++雖然是C的超集,然而用抽象機制擴展C語言的重大意義就在于用抽象去覆蓋C當中裸露的種種語言特性,讓程序員能夠在一個更自然的抽象層面上編程,比如你不是用int*加一個數組大小n來表示一個數組,而是用可自動增長的vector;比如你不是用malloc/free,而是用智能指針和RAII技術來管理資源;比如你不是用一個只包含數據的結構體加上一組函數來做一個暴露的類,而是使用真正的ADT。比如你不是使用second-class的返回值來表達錯誤,而是利用first-class的語言級異常機制等等。然而,C畢竟是C++的源頭,剝開C++的抽象外衣,底層仍然還是C;而且,更關鍵的是,在實際編碼當中,有時候還的確要“C”一把,比如在模塊級的二進制接口封裝上。Bjarne也說過,OO/GP這些抽象機制只有用在合適的地方才是合適的。當人們手頭有的是錘子的時候,很容易把所有的目標都當成釘子,有時候C的確能夠提供簡潔高效的解決方案,比如C標準庫里面的printf和fopen(此例受云風的啟發)的使用界面就是典型的例子。簡而言之,理解C語言的精神不僅有助于更好地理解C++,更理性地使用C++,而且也有其實踐意義——這就是推薦《The C Programming Language》(以下簡稱TCPL)的原因。此外,建議在閱讀《Accelerated C++》之前先閱讀《The C Programming Language》。因為,一,《The C Programming Language》非常薄。二,如果你帶著比較的眼光去看問題,看完《The C Programming Language》再看《Accelerated C++》,你便會更深刻的理解C++語言引入抽象機制的意義和實際作用。
第四本
《Accelerated C++》固然寫得非常漂亮,但正如所有漂亮的入門書一樣,它的優點和弱點都在于它的輕薄短小。短短3百頁,對現代C++的運用精神作了極好的概述。然而要熟練運用C++,我們還需要更多的講解,這個時候一本全面但又不鉆語言牛角尖,從“語言是如何支持抽象設計”的角度而不是“為了講語言特性而講語言特性”的角度來介紹一門語言的書便至關重要,在C++里面,我還沒有見到比C++之父本人的《The C++ Programming Language》(以下簡稱TC++PL)做得更好的,C++之父本人既有大規模C++運用的經驗又有語言設計思想的最本質把握,因此TC++PL才能做到高屋建瓴,不為細節所累;同時又能做到實踐導向,不落于為介紹語言而介紹語言的巢臼。最后有一個需要提醒的地方,TC++PL其實沒有它看起來那么厚,因為真正介紹語言的內容只有區區500頁(第一部分:基礎;第二部分:抽象機制;以及第四部分:用C++設計),剩下的是介紹標準庫的,可以當作Manual(參考手冊)。
建議3:CSAPP &TCPL& AC++&TC++PL。
是的,在C++方面登堂入室并不需要閱讀多得恐怖的所謂“經典”,至于為什么這些“經典”無需閱讀,前面已經講的很詳細了。其實你只需要這四本書,就可以奠定一個深厚的基礎,以及對C++的成熟理性的現代運用理念。其余的書都可以當成參考資料,用到的時候再去翻閱,即:
建議4:實踐驅動地學習。
實踐驅動當然不代表什么基礎都不打,直接捋起袖管就上。不管運用哪種工具,首先都需要知道關于它的一定程度的基本知識(包括應該怎么用,和不應該怎么用)。知道應該怎么用可以幫你發揮出它的正確和最大效用,知道不應該怎么用則可以幫你避免用的過程中傷及自身的危險。這就是為什么我建議你看四本書,以及建議你要了解C++中的陷阱(大部分來自C,因此你可以閱讀《C缺陷和陷阱》)的原因。
實踐驅動代表著一旦一個扎實的基礎具備了之后獲得延伸知識的方式。出于環境和心理的原因,C++學習者們在這條路上走錯的幾率非常大,許多人乃至以上來就拿Effective C++&More Effective C++、Inside C++ Object Model這類書去讀(是的,我也是,所以我才會在這里寫下這篇文章),結果讀了一本又一本,出現知道虛函數實現機制的每個細節卻不知道虛函數作用的情況。
實踐驅動其實很簡單:實踐+查文檔。知識便在這樣一個簡單的循環中積累起來。實踐驅動的最大好處就是你學到的都是實踐當中真正需要的,屬于那“80%”最有用的。而查文檔的重要性前面已經說過了,但對于C++實踐者來說,哪些“文檔”是非常重要的呢?
第二本
《C++ Coding Standard》。無需多作介紹,這是一本濃縮了C++社群多年來寶貴的經驗結晶的書,貼近實踐,處處以80%場景為主導,不鉆語言旮旯,用本為主…總之,非常值得放在手邊時時參閱。因為書很薄,所以也不妨先往腦袋里面裝一遍。書中的101條建議的介紹都很簡略,并且指出了詳細介紹的延伸閱讀,在延伸閱讀的時候還是要注意不要陷入無關的細節和不必要的技巧中,時時抬頭看一看你需要解決的問題。在C++編碼標準方面,Bjarne也有一些建議。
第一本
《The Pragmatic Programmer》,用本程序員的杰作;雖然不是一本C++的書,但其介紹的實踐理念卻是所有程序員都需要的。
第三本
《Code Complete, 2nd Edition》,這是一本非常卓越的參考資料,涉及開發過程的全景,有大量寶貴的經驗。你未必要一口氣讀完,但你至少應該知道它里面都寫了哪些內容,以便可以回頭參閱。
其它
所有優秀的技術書籍都是資料來源。一旦養成了查文檔的習慣,所有的電子書、紙書、網絡上的資源實際上都是你的財富。不過,查文檔的前提是你要從手邊的問題分析出應該到什么地方去查資料,這里,分析問題的能力很重要,因此:
建議5:思考。
這個建議就把我們帶到了第四本書:
第四本:
《你的燈亮著嗎?》。不作介紹,自己閱讀,這本書只有一百多頁,但精彩非常,妙趣橫生。
最后,要想理性地運用一門語言,不僅需要看到這門語言的特點,還要能夠從另一個角度去看這門語言——即看到它的缺點,因為從心理上——
事實10:一旦我們熟悉了一門語言之后,就容易不知不覺地在其框架下思考,受到語言特性的細節的影響,作出second-class的設計。
對于像C++這樣的在抽象機制上作了折衷的語言,尤其如此,思考容易受到語言機制本身細節的影響,往往在心里頭還沒想好怎么抽象,就已經確定了使用什么語言機制乃至技巧;更有甚者是為了使用某個特性而去使用某個特性。然而,實際上,我們應該——
建議6:脫離語言思考,使用語言實現。
關于設計的一般理念,Eric Raymond在《The Art of Unix Programming》的第二部分有非常精彩的闡述。
此外,除了脫離語言的具體抽象機制來思考設計之外,學習其它語言對同類抽象機制的支持也是非常有益的,正如老話所說,“兼聽則明”。前一陣子reddit上也常出現“How Learning XXX help me become a Better YYY programmer”(其中XXX和YYY指代編程語言)的帖子,正是這個道理,這就把我們帶到了最后一個建議:學習其它語言。
建議7:學習其它語言。
如果你是一個系統程序員,你可能會覺得沒有必要學習其它語言,然而未必如此,你未必需要精通其它語言,而是可以去試著了解其它語言的設計理念,是如何支持日常編程中的設計的。這一招非常有利于在使用你自己的語言編程時心理上脫離語言機制細節的影響,作出更好的抽象設計。
尾聲
建議8(可選):重讀本文。
注:這篇文章的目的是給國內的C++學習者(尤其是初學者)一個可操作的建議。我打算不斷修訂并完善它;因為這是根據我個人的經驗來寫的,而基于我對C++的熟悉程度,可能會有地方并不能完完全全站到初學者的視角來看問題。我估計會有這樣的地方,所以,如果有任何建議,請發郵件給我:pongba@gmail.com
本文來自: 書部落-電子書下載(www.shubulo.com)
詳細出處參考:http://www.shubulo.com/thread-40646-1-1.html
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -