簡介
Bjarne Stroustrup博士,1950年出生於丹麥,先後畢業於丹麥阿魯斯大學和英國劍橋大學,AT&T大規模程式設計研究部門負責人,AT&T、貝爾實驗室和ACM成員。1979年,B. S開始開發一種語言,當時稱為“C with Class”,後來演化為C++。1998年,ANSI/ISO C++標準建立,同年,B. S推出了其經典著作The C++ Programming Language的第三版。C++的標準化標誌著B. S博士傾20年心血的偉大構想終於實現。但是,計算技術的發展一日千里,就在幾年前人們還猜想C++最終將一統天下,然而隨著Internet的爆炸性增長,類似Java、C#等新的、現代感十足的語言咄咄逼人,各種Script語言更是如雨後春筍紛紛湧現。在這種情況下,人們不禁有些惶恐不安。C++是不是已經過時了呢?其前景如何?標準C++有怎樣的意義?應該如何學習?我們不妨看看B. S對這些問題的思考。以下文字是譯者從Stroustrup1998年之後發表的若干文章、談話筆記中精選出來的,由於出處不一,內容多有重複,為保持完整,亦一併譯出。
以下內容選自B. S在自己主頁上發表的FAQ
1. 請談談C++書。
沒有,也不可能有一本書對於所有人來說都是最好的。不過對於那些真正的程式設計師來說,如果他喜歡從“經典風格”的書中間學習一些新的概念和技術,我推薦我的The C++ Programming Language, 1998年的第三版和特別版。那本書講的是純而又純的C++,完全獨立於平台和庫(當然得講到標準庫)。該書面向那些有一定經驗的程式設計師,幫助他們掌握C++,但不適合毫無經驗的初學者入門,也不適合那些臨時程式設計師品嘗C++快餐。所以這本書的重點在於概念和技術,而且在完整性和精確性上下了不少功夫。如果你想知道為什麼C++會變成今天的模樣,我的另一本書The Design and Evolution of C++ 能給你滿意的答案。理解設計的原則和限制能幫助你寫出更好的程式。http://www.hudong.com/wiki/www.accu.com%E6%98%AF%E6%9C%80%E5%A5%BD%E7%9A%84%E6%9B%B8%E8%A9%95%E7%B6%B2%E7%AB%99%E4%B9%8B%E4%B8%80,很多有經驗的程式設計師在此仗義執言,不妨去看看。
2. 學習C++要花多長時間?
這要看你說的“學習”是什麼意思了。如果你是一個Pascal程式設計師,你應該能很快地使你的C++水平達到與Pascal相近的程度;而如果你是一個C程式設計師,一天之內你就能學會使用C++進行更出色的C風格編程。另一方面,如果你想完全掌握C++的主要機制,例如數據抽象,面向對象編程,通用編程,面向對象設計等等,而此前又對這些東西不很熟悉的話,花上個一兩年是不足為奇的。那么是不是說這就是學習C++所需要的時間呢?也許再翻一番,我想打算成為更出色的設計師和程式設計師最起碼也要這么長的時間。如果學習一種新的語言不能使我們的工作和思想方式發生深刻的變革,那又何苦來哉?跟成為一個鋼琴家或者熟練掌握一門外語相比,學習一種新的、不同的語言和編程風格還算是簡單的。
3. 了解C是學習C++的先決條件嗎?
否!C++中與C相近的子集其實比C語言本身要好學,類型方面的錯誤會少一些,也不像C那樣繞圈子,還有更好的支持庫。所以應該從這個子集開始學習C++。
4. 要想成為真正的OO程式設計師,我是不是得先學習Smalltalk?
否。如果你想學Smalltaok,儘管去學。這種語言很有趣,而且學習新東西總是一個好主意。但是Smalltalk不是C++,而且把Smalltalk的編程風格用在C++里不會有什麼好結果。如果你想成為一個出色的C++程式設計師,而且也沒有幾個月的時間百無聊賴,請你集中力量學好C++以及其背後的思想。
5. 我如何開始學習C++?
這取決於你的基礎和學習動機。如果你是個初學者,我想你最好找個有經驗的程式設計師來幫助你,要不然你在學習和實踐中不可避免的犯下的種種錯誤會大大地打擊你的積極性。另外,即使你的編譯器配備了充足的文檔資料,一本C++書籍也永遠是必不可少的,畢竟文檔資料不是學習編程思想的好教材。
選擇書籍時,務必注意該書是不是從一開始就講授標準C++,並且矢志不渝地使用標準庫機制。例如,從輸入中讀取一個字元串應該是這樣的:
string s; // Standard C++ style
cin >> s;
而不是這樣的:
char s【MAX】;/* Standard C style */
scanf("%s",s);
去看看那些紮實的C++程式設計師們推薦的書吧。記住,沒有哪本書對所有人來說都是最好的。
另外,要寫地道的C++程式,而避免用C++的語法寫傳統風格的程式,新瓶裝舊酒沒多大意義。
(遺憾的是,目前在市面上的中文C++教材中,符合B. S的這個標準的可以說一本都沒有,大家只好到網上找一些英文的資料來學習了。——譯者)
6. 怎樣改進我的C++程式?
不好說。這取決於你是怎么使用該語言的。大多數人低估了抽象類和模板的價值,反過來卻肆無忌憚地使用造型機制(cast)和宏。這方面可以看看我的文章和書。抽象類和和模板的作用當然是提供一種方便的手段建構單根的類層次或者重用函式,但更重要的是,它們作為接口提供了簡潔的、邏輯性的服務表示機制。
7. 語言的選擇是不是很重要?
是,但也別指望奇蹟。很多人似乎相信某一種語言能夠解決他們在系統開發中遇到的幾乎所有問題,他們不斷地去尋找完美的程式語言,然後一次次的失敗,一次次的沮喪。另外一些人則將程式語言貶為無關緊要的細節,把大把大把的銀子放在開發流程和設計方法上,他們永遠都在用著COBOL, C和一些專有語言。一種優秀的語言,例如C++,能幫助設計者和程式設計師做很多事情,而其能力和缺陷又能夠被清楚地了解和對待。
8. ANSI/ISO標準委員會是不是糟蹋了C++?
當然不是!他們(我們)的工作很出色。你可以在一些細節上找些歪理來挑刺,但我個人對於這種語言以及新的標準庫可是欣欣然。ISO C++較之C++的以前版本更出色更有條理。相對於標準化過程剛剛開始之初,你今天可以寫出更優雅、更易於維護的C++程式。新的標準庫也是一份真正的大禮。由於標準庫提供了strings, lists, vectors, maps以及作用於其上的基本算法,使用C++的方式已經發生了巨大的變化。
9. 你現在有沒有想刪除一些C++特性?
沒有,真的。問這些問題的人大概是希望我回答下面特性中的一個:多繼承、異常、模板和RTTI。但是沒有它們,C++就是不完整的。在過去的N年中,我已經反覆考慮過它們的設計,並且與標準委員會一起改進了其細節,但是沒有一個能被去掉又不引起大地震。
從語言設計的角度講,我最不喜歡的部分是與C兼容的那個子集,但又不能把它去掉,因為那樣對於在現實世界裡工作的程式設計師們來說傷害太大了。C++與C兼容,這是一項關鍵的設計決策,絕對不是一個叫賣的噱頭。兼容性的實現和維護是十分困難的,但確實使程式設計師們至今受益良多。但是現在,C++已經有了新的特性,程式員們可以從麻煩多多的C風格中解脫出來。例如,使用標準庫里的容器類,象vector,list, map, string等等,可以避免與底層的指針操作技巧混戰不休。
10. 如果不必和C兼容,你所創造的語言是不是就會是Java?
不是,差得遠。如果人們非要拿C++和Java來作比較,我建議他們去閱讀The Design and Evolution of C++,看看C++為什麼是今天這個樣子,用我在設計C++時遵從的原則來檢驗這兩種語言。這些原則與SUN的Java開發小組所持的理念顯然是不同的。除了表面語法的相似性之外,C++與Java是截然不同的語言。在很多方面,Java更像Smalltalk(譯者按:我學習Java時用的是Sun的培訓教材,裡面清楚地寫道:Java在設計上採用了與C++相似的語法,與Smalltalk相似的語義。所以可以說Java與C++是貌合神離,與Smalltalk才是心有靈犀)。Java語言相對簡單,這部分是一種錯覺,部分是因為這種語言還不完整。隨著時間的推移,Java在體積和複雜程度上都會大大增長。在體積上它會增長兩到三倍,而且會出現一些實現相關的擴展或者庫。這是一條每個成功的商業語言都必須走過的發展之路。隨便分析一種你認為在很大範圍內取得了成功的語言,我知道肯定是無有例外者,而且實際上這非常有道理。
上邊這段話是在Java 1.1推出之前寫的。我確信Java需要類似模板的機制,並且需要增強對於固有類型的支持。簡單地說,就是為了基本的完整性也應該做這些工作。另外還需要做很多小的改動,大部分是擴展。1998年秋,我從James Gosling(Java語言的創始人——譯者)那裡得到一份建議書,說是要在Java中增加固有類型、操作符重載以及數學計算支持。還有一篇論文,是數學分析領域的世界級大師,伯克利大學的W. Kahan教授所寫的How Java’s Floating-Point Hurts Everyone Everywhere(“且看Java的浮點運算如何危害了普天下的芸芸眾生”——譯者),揭露了Java的一些秘密。
我發現在電視和出版物中關於Java的鼓吹是不準確的,而且氣勢洶洶,讓人討厭。大肆叫囂凡是非Java的代碼都是垃圾,這是對程式設計師的侮辱;建議把所有的保留代碼都用Java重寫,這是喪心病狂,既不現實也不負責任。Sun和他的追隨者似乎覺得為了對付微軟罪惡的“帝國時代”,就必須如此自吹自擂。但是侮辱和欺詐只會把那些喜歡使用不同程式語言的程式設計師逼到微軟陣營里去。
Java並非平台無關,它本身就是平台。跟Windows一樣,它也是一個專有的商業平台。也就是說,你可以為Windows/Intel編寫代碼,也可以為Java/JVM編寫代碼,在任何一種情況下,你都是在為一個屬於某個公司的平台寫代碼,這些代碼都是與該公司的商業利益扯在一起的。當然你可以使用任何一種語言,結合作業系統的機制來編寫可供JVM執行的程式,但是JVM之類的東西是強烈地偏向於Java語言的。它一點也不像是通用的、公平的、語言中立的VM/OS。
私下裡,我會堅持使用可移植的C++作大部分工作,用不同的語言作餘下的工作。
(”Java is not platform-independent, it is the platform”,B. S的這句評語對於C++用戶有著很大的影響,譯者在國外的幾個新聞組裡看到,有些C++高手甚至把這句話作為自己的簽名檔,以表明對Java的態度和誓死捍衛C++的決心。實際上有很多程式設計師不光是把自己喜愛的語言當成一種工具,更當成一種信仰。——譯者)
11. 您怎么看待C#語言?
就C#語言本身我沒什麼好說的。想讓我相信這個世界還需要另外一個專有的語言可不是一件容易的事,而且這個語言還是專門針對某一個專有作業系統的,這就更讓我難以接受。直截了當地說,我不是一個專有語言的痴迷者,而是一個開放的正式標準的擁護者。
12. 在做大項目時,您是不是真的推薦Ada,而不是C++?
當然不是。我不知道這是誰傳出來的謠言,肯定是一個Ada信徒,要么是過分狂熱,要么是不懷好意。
13. 你願不願意將C++與別的語言比較?
抱歉,我不願意。你可以在The Design and Evolution of C++的介紹性文字里找到原因。
有不少書評家邀請我把C++與其它的語言相比,我已經決定不做此類事情。在此我想重申一個我很久以來一直強調的觀點:語言之間的比較沒什麼意義,更不公平。主流語言之間的合理比較要耗費很大的精力,多數人不會願意付出這么大的代價。另外還需要在廣泛的套用領域有充分經驗,保持一種不偏不倚、客觀獨立的立場,有著公正無私的信念。我沒時間,而且作為C++的創造者,在公正無私這一點上我永遠不會獲得完全的信任。
人們試圖把各種語言拿來比較長短,有些現象我已經一次又一次地注意到,坦率地說我感到擔憂。作者們盡力表現的公正無私,但是最終都是無可救藥地偏向於某一種特定的應用程式,某一種特定的編程風格,或者某一種特定的程式設計師文化。更糟的是,當某一種語言明顯地比另一種語言更出名時,一些不易察覺的偷梁換柱就開始了:比較有名的語言中的缺陷被有意淡化,而且被拐彎抹角地加以掩飾;而同樣的缺陷在不那么出名的語言裡就被描述為致命硬傷。類似的,有關比較出名的語言的技術資料經常更新,而不太出名的語言的技術資料往往是幾年以前的,試問這種比較有何公正性和意義可言?所以我對於C++之外的語言的評論嚴格限制在一般性的特別特定的範疇里。
換言之,我認為C++是大多數人開發大部分應用程式時的最佳選擇。
14. 別人可是經常拿他們的語言與C++比來比去,這讓你感到不自在了嗎?
當這些比較不完整或者出於商業目的時,我確實感覺不爽。那些散布最廣的比較性評論大多是由某種語言,比方說Z語言的擁護者發表的,其目的是為了證明Z比其它的語言好。由於C++被廣泛地使用,所以C++通常成了黑名單上的頭一個名字。通常,這類文章被夾在Z語言的供貨商提供的產品之中,成了其市場競爭的一個手段。令人震驚的是,相當多的此類評論引用那些在開發Z語言的公司中工作的雇員的文章,而這些經不起考驗文章無非是想證明Z是最好的。特別是在這些比較中確實有一些零零散散的事實,(所以更具欺騙性——譯者),畢竟沒有一種語言在任何情況下都是最好的。C++當然不完美,不過請注意,特意選擇出來的事實雖然好像正確,但有時是完全的誤導。
以後再看到語言比較方面的文章時,請留心是誰寫的,他的表述是不是以事實為依據,以公正為準繩,特別是評判的標準是不是對於所引述的每一種語言來說都公平合理。這可不容易做到。
15. 在做小項目時,C優於C++嗎?
我認為非也。除了由於缺乏好的C++編譯器而導致的問題之外,我從沒有看到哪個項目用C會比用C++更合適。
(不過現在C++編譯器導致的問題還是不可忽略的,當你看到同樣功能的C++程式可執行代碼體積比C大一倍而且速度慢得多時,會對此有所感觸的。——譯者)
以下內容來自Visual C++ Developer’s Journal主編Elden Nelson 2000年3月對B. S的專訪
16. 如果您現在有機會從頭設計C++語言,您會做些什麼不同的事情?
當然,你永遠都不可能重新設計一種語言,那沒有意義,而且任何一種語言都是它那個時代的產物。如果讓我今天再設計一種語言,我仍然會綜合考慮邏輯的優美、效率、通用性、實現的複雜程度和人們的喜好。要知道人們的習慣對於他們的喜好有著巨大的影響。
現在,我會尋找一種簡單得多的語法,我會把類型系統的衝突問題限制在很少的幾種情況里,而且你能很容易的發現這些問題。這樣就能夠很容易的禁止不安全的操作。
(B. S的原則是:對於糟糕的代碼,就算是不能完全禁止,至少也要讓它大白於天下,而不是藏在陰暗的角落裡暗箭傷人。C++實際上已經提供了這樣的機制,例如如果你使用象reinterpret_cast(pointer)這樣的很明顯是非常糟糕的表達式進行造型,別人會很容易地找到問題所在。只不過C++仍然允許你使用傳統的、C風格的造型機制,而又有不少人一直使用這種老式的風格,所以才引來麻煩多多。B. S的意思是說,要是現在能夠禁止老式的風格該有多好!作為語言設計者的他,恐怕是沒有這個機會了,但是作為語言使用者的我們,卻還有很大的希望去改進自己的代碼。何去何從,應該是我們深思的時候了。——譯者)
我還會把核心語言的體積儘可能搞得小一些,包括類和模板的關鍵的抽象特性,而把很多其它的語言特性放在庫里來解決。當然我也會保證核心語言足夠的強大,使得那些庫本身也足以用這個核心語言來產生。我可不希望標準庫的創建需要用到什麼不屬於該語言本身的神秘機制。另外我會讓這個核心語言的定義更加精確。(有不少新的語言在建庫時就使用了一些“不屬於該語言本身的神秘機制”,比如VB和JAVA。從理論上講,這是近乎無賴的行徑,所以B. S不以為然。不過從實用出發倒也無傷大雅。——譯者)
最重要的是,我會在該語言被廣泛使用之前儘可能維持一個很長的醞釀期,這樣我可以以其他人的反饋為基礎進行改進。這可能是最困難的,因為一旦有什麼東西是明顯出色和有前途的,大家就會蜂擁而至的來使用它,此後作任何不兼容的修正都會是非常困難的。
我相信這些思想與我當初設計C++時的理念是非常類似的,同樣也是這些思想指引著一二十年來C++的不斷演化。當然,我認為現在還沒有什麼東西能讓我覺得像是“完美的語言”。
17. 您預期C++做哪些增強,會不會刪掉一些東西?
很不幸,雖然有一些東西很應該扔掉,但恐怕很難真的刪掉任何東西。第一個應該拋棄的東西就是C風格的造型機制和類型截斷轉換。就算不禁止,編譯器的作者們至少也應該對這種行為給與強烈的警告。我希望能用類似vector的東西徹底取代數組,但這顯然是不肯能的。不過如果程式設計師們能主動使用vector來代替數組,就會立刻受益匪淺。關鍵是你不必再使用C++中最複雜難纏的技巧了,現在有優秀得多的替代方案。
至於主要的特性,我沒想去掉任何東西。特別是那些把C++與C區別開來的主要特性恐怕沒法風平浪靜的被拋掉。通常問這些問題的人是希望我挑出諸如多繼承、異常、模板等機制來接受批判。所以在這我想大聲講清楚,我認為多繼承機制對於靜態類型語言實現繼承性來說是必需的,異常機制是在大系統中對付錯誤的正確方法,模板機制是進行類型安全的、精緻的和高效的程式設計的靈丹妙藥。我們可以在小的細節上對於這些機制挑挑刺,但在大的方面,這些基本的概念都必須堅持。
現在我們仍在學習標準C++,也正在標準所提供的特性基礎上發展出更新的、更有趣的編程技術。特別是人們剛剛開始使用STL和異常機制,還有很多高效強大的技術鮮為人知,所以大可不必急匆匆的跑去增加什麼新的機制。
我認為當前的重點是提供很多新的、比以前更加精緻的、更有用的庫,這方面潛力巨大。例如,如果有一個能被廣泛使用的、更精緻的支持並發程式設計的庫,那將是一大福音——C風格的執行緒庫(例如Pthread——譯者)實在不夠好。我們也就可以與各種其他的系統,例如SQL以及不同的組件模型更好地契合起來。數值計算領域的人們在這方面好像已經走在了前面,類似像Blitz++、POOMA、MTL之類的高效而精緻的庫的開發已經取得了非凡的成就。(譯者在Internet上造訪了Blitz++和POOMA的主頁,前者是一個高性能數學庫,據稱其性能與Fortran 77不相上下,同時又支持大量的C++特性。我想凡是對於數值計算領域有所了解的人都知道這有多么偉大的意義。POOMA則是一個專門研究C++並行數學算法的項目,它的前景更加不可限量。譯者非常認同B. S的這個觀念。——譯者)
有了足夠的經驗之後,我們就能更好的決定應該對標準做些什麼調整。
18. 顯然,這幾年世界變了,正在走向一個以Web為中心、分散式計算為主流的時代。那么您覺得C++還能維持其地位嗎?程式設計師們可不可能把若干種專用語言(比如Perl、Javascript)綜合運用以徹底取代某一種通用語言?(C++就是這樣的通用語言——譯者)為了配合新的計算模式,C++及其標準庫應該做怎樣的調整?
從來沒有哪一種語言能適合所有的工作,我恐怕以後也不會有。實際系統通常是用多種語言和工具構造起來的。C++只是想成為若干語言和工具中的一個,當某些專用語言在其領域裡特別突出時,它們可以與C++互為補充。也就是說,我覺得如果大多數現在的專用語言能藉助特定領域的C++庫共同工作的話,它們會表現得更出色。腳本語言通常導致難以維護的代碼,而且也沒有給程式的結構、可擴展性和可維護性的最佳化留下什麼餘地。
我不敢肯定未來的代碼是否真的會是以Web為中心的。就算是直接處理Web的系統也主要是由處理本地資源,如IP連線之類的程式模組構成的。
地理上的分布性以及伺服器軟體對於並發機制的高度依賴對於系統的建造者來說的確是個挑戰。有些針對上述問題的庫已經出現,也許我們將會看到它們最終得以標準化。當然,一些原操作和保證規則應該被加到核心語言中以提供對這些庫的更佳支持。
總的來說,對於Web和網路,我們非常需要一個真正的系統/網路級的安全模型。指望JavaScript之類的腳本語言實現這個模型無異於白日做夢。注意,我也沒說C++提供了這個問題的解決方式。C++的重心是高效的訪問系統資源,而不是反欺詐。
19. 您看C++未來的走向如何?在接下來的10年裡它會衰落嗎?或者是基本保持現在的形式?或者發展變化呈不同的形式?
C++有著最美好的未來。用它你能寫出偉大的代碼。除了故意進行惡意欺詐,C++仍將是開發高性能、高複雜度系統的最好語言。據我所知,沒有那種語言能在通用性、效率和精緻三方面的統一上可與C++相提並論。
我沒看到C++有衰落的徵兆。在我能預見的未來里,它的用途還會不斷增長。當然,在未來的十年里我們會看到一些變化,但不會像你想得那么顯著。跟每一種語言一樣,C++也會發展變化。“語言專家們”要求改進的喧囂聲震耳欲聾,但是系統開發者們的基本請求是保持穩定。
C++會改進,但是這些改進將主要是為了反映從實踐中得來的經驗教訓,而不會是為了追風尚趕時髦。為了更高效地使用一些新的編程技術,比如通用編程技術,可能會增加一些小的特性。會有大量的庫湧現,我預期會出現一種嶄新的、更出色的庫支持機制。我希望新的擴展主要集中在支持抽象方面的一般特性,而不是為支持某些特殊任務的特定機制。
例如,“屬性”這個概念是很有用的,但我不認為在一種通用程式語言中有它的容身之地。用標準C++的一組類可以很容易地支持這一概念。如果我們感覺那族類對於“屬性”這一概念的支持不盡如人意,也不會立刻跑去在語言裡增加屬性機制,而是仔細考慮如何改進類和模板以幫助庫設計人員儘可能接近“屬性”這個概念。也許通過改進函式對象的機制能夠給這個問題一個滿意的答覆。
為了使C++在接下來的十幾年中保持靈活可變,很基本的一點就是不要讓標準C++趕什麼學術或者商業的時髦。人們要求增加的特性中很大一部分通過使用現有的標準C++開發新庫的方式都可以實現。還有,事實上人們渴望得到的很多特性已經被包括在標準C++中,並且被最新的編譯器支持。對許多程式設計師來說,提高代碼質量的最佳途徑不是追求什麼語言擴展,而是好好地、慢慢地品味最新的C++技術書籍(可惜我們到目前為止連這種機會都沒有——譯者)。
20. 您怎么看待腳本語言的興旺態勢?特別是Python,似乎提供了一種學習OO技術的更簡單的途徑
有些語言很不錯。比如Python,我很喜歡。但是我認為你從不同的語言中學到的OO技術是不完全相同的。當然,每一個專業的程式設計師都需要通曉幾門語言,並且了解各種語言在編程和設計技術上的不同。
在我看來,用腳本語言建造的系統與用C++那樣的通用語言建造的系統大不相同。從兩類語言中學到的技術區別明顯。在OO技術里也不存在什麼通用部分對於各種系統的高效建造來說都是至關重要的。
21. 有沒有計畫往標準C++里增加一些新的特性以支持分散式計算?
沒有,我也不認為有這個必要。用更好的庫就差不多能解決問題了。最多,為了支持這類的庫,我們可能會增加一些低級的原操作和規則
22. 未來C++有沒有可能定一個可移植的二進制接口?
如果你說的“可移植”是指跨硬體和塊作業系統的可移植,我想回答是不會。我們當然可以設計一個解釋器或者虛擬機(如同Java的做法——譯者),但這樣一來,由於無法以最優的方式訪問系統資源,C++的能力就會受到削弱,。我真正希望在不遠的將來能夠看見的東西是platform ABIs。例如,有人正在努力為Intel新的IA64體系定義C++ ABI,我想這些努力會得到用戶們的巨大支持。
能夠把不同編譯器產生的代碼編譯在一起將會是一項十分有意義的事情。
23. 在不少流行領域,C++正在漸漸失去光芒,因為它要求人們花很大的精力去對付一些很基本的工作,比如管理記憶體(因為沒有垃圾收集機制),管理模組之間的依賴性(因為沒有包機制),管理組件的版本。C++缺乏一些現代語言已經視為標準的特性。比如傳言中最酷的Java語言就特別重視這些問題。那么在解決這些問題是否會導致C++的發展背離其根本宗旨呢?C++應該怎樣發展以保證我們在這種語言上的投資能有合理的回報,而不是被迫去重新使用另一種語言?
我倒還沒有注意到C++比以前用的少了。相反,我看到的指標表明C+的使用還在穩定地增長著。只不過這種基數很大的穩定增長以及在標準性、移植性和庫方面的不斷提高並沒有造成什麼具有欺騙性的新聞效應而已。我認為你所說的“失去光芒”只不過是市場推銷和新聞意義上的現象。
如果你需要垃圾收集機制的話,你可以在C++應用程式中插入一個垃圾收集器。有不少自由的和商業的垃圾收集器已經在重要的實踐中被證明是很出色的。
如果你不想使用垃圾收集機制,也沒關係。你可以使用標準容器類,它們大大減少了對於顯式分配和回收記憶體的需要。這樣,使用現代的庫和現代的編程風格,你能夠避免大部分的記憶體管理問題。
同樣的技術還能夠用來避免一般資源的管理問題。並不是只有記憶體才會泄漏,執行緒句柄、檔案、互斥鎖、網路連線等都是重要的資源,為了建立可靠的系統,這些資源必須被正確的管理。如果你覺得有了垃圾收集機制就可以解決所有的資源管理問題,那么你最好趕快從美夢中醒來。
C++提供了很多機制來管理一般性的資源。關鍵的手段——“獲取資源就是初始化”——可以使用函式對象來管理生存期問題。語言中關於對象的局部構造和異常機制對這項技術提供了支持。
某些語言的狂熱支持者總是用諷刺漫畫的筆法描述C++,然而C++實際上要好得多。特別是我覺得很多其他的特性已經泛濫不堪了,在C++中,通常這些特性能夠很容易的被模擬出來。相反的,新的語言在推廣的過程中總是不斷地增加新的特性,這就是為什麼從一種語言誕生到被廣泛使用,其體積通常會增加個兩三倍。
目前,最為個人和組織,對於C++的最好投資就是去更好地理解標準C++和現代的C++設計編程技術。大多數人使用C++的方式實際上停留80年代中期的水平,甚至比那更陳舊。
至於模組依賴性問題,我的觀點是,在程式語言的工作和系統的工作之間應該有一個明顯的界線,依賴關係應該儘可能地與程式語言分開,而由系統來支持。
我不認為組建版本的問題應該由程式語言來解決,這是一個系統範疇里的問題,在語言裡應該通過提供相應的庫來解決。C++有這樣的機制。解決這樣的問題不會使C++偏離軌道。但是給C++增加很多特殊的特性就會使C++偏離軌道,而且在保持可移植性和平台獨立性方面也會是一個倒退。
24. 標準C++推出有段時間了,Java也大踏步地往前走而且取得了顯著的進步,您現在怎么比較java與c++?您覺得Java想要變成像C++一樣“好”的語言還需要做些什麼?您舉的C++從Java身上學到了什麼經驗嗎?有沒有什麼Java的特性您認為是可以被C++吸納的?
我不比較語言。做好這項工作是十分困難的,而且很少具有專業水準。
我認為C++的進步會是主要以它的用戶在使用中遇到的問題以及其自身邏輯為基礎。當然,其他語言中的某些思想也會被考慮,但不能被簡單的移花接木過來。你必須審視那些機制在技術上和思想上的背景,並且找到在C++中支持這些技術的最佳方案。
有時最好的選擇是綜合使用幾種語言。畢竟沒有任何一種語言是放之四海而皆優的。C++現在是,將來也繼續會是在廣泛套用領域中最好的語言之一。但是,我們不能被拉下水,不能把所有可能的特性都加到C++裡面來向大眾獻媚。我認為Java和C++現在和將來都會是十分不同的語言,語法相似,但背後的對象模型明顯不同。
對於我來說,一個很重要的區別是C++有一個ISO標準,而Java則是一個專有語言。
25. 在Java剛剛出現的那幾年,有很多欺騙性的言論說它將會是終極語言,會取代C++。您覺得在過去兩三年里Java對C++的追隨者們有什麼影響?
到現在關於Java的不實之辭也還隨處可見。暫且不提Java在過去5年間的創紀錄的發展,狂熱的大眾似乎認為Java將最終取代的不僅僅是C++,而且還有所有其他的程式語言。但在另一方面,C++的使用仍在繼續增長。我不認為Java對於C++的影響已經使得人們轉而把本來打算用來創造更好的C++工具庫的資源調過去開發Java工具庫。Java對於學習編程的人來說沒有太多的新東西,所以對於C++的定義也沒什麼影響。在那個領域,Java還得努力追趕。例如,我認為為Sun遲早會往Java里加入類似模板的機制。
人們應該認識到C++和Java的目標是何等的不同。 以C++的設計理念來衡量Java,或是以Java的設計理念來衡量C++,得出的結論都不會很好。
在訪談即將結束時,或許我該再次表明態度:C++仍然是我喜愛的語言,在寫代碼時你會發現沒有那種語言能像它那樣在如此廣泛的套用領域和平台上同時達成如此的高效與精緻。
Bjarne Stroustrup 語錄
一、致讀者
1. 在編程式時,你是在為你針對某個問題的解決方案中的思想建立起一種具體表示。讓程式的結構儘可能地直接反映這些思想:
★.如果你能把“它”看成一個獨立的概念,就把它做成一個類。
★.如果你能把“它”看成一個獨立的實體,就把它做成某個類的一個對象。
★.如果兩個類有共同的界面,將此界面做成一個抽象類。
★.如果兩個類的實現有某些顯著的共同東西,將這些共性做成一個基類。
★.如果一個類是一種對象的容器,將它做成一個模板。
★.如果一個函式實現對某容器的一個算法,將它做成為對一族容器可用的模板函式。
★.如果一組類、模板等相互之間有邏輯聯繫,將它們放進一個名字空間裡。
2. 在你定義一個並不是實現某個像矩陣或複數這樣的數學對象的類時,或者定義一個低層的類型如連結表的時候:
★.不要使用全局數據(使用成員)。
★.不要使用全局函式。
★.不要使用公用數據成員。
★.不要使用友元,除非為了避免a或c。
★.不要在一個類裡面放“類型域”(指那種為了說明一個類所存儲數據的情況而放置的標誌域) ;採用虛函式。
★.不要使用線上函式(inline function),除非作為效果顯著的最佳化。
二、C++ 概覽
1. 不用害怕,一切都會隨著時間的推移而逐漸明朗起來。
2. 你並不需要在知道了C++的所有細節之後才能寫出好的C++程式。
3. 請特別關注程式設計技術,而不是各種語言特徵。
三、標準庫概覽
1. 不要像重新發明車輪那樣企圖做每件事;去使用庫。
2. 不要相信奇蹟;要理解你的庫能做什麼,它們如何做,它們做時需要多大的代價。
3. 當你遇到一個選擇時,應該優先選擇標準庫而不是其他的庫。
4. 不要認為標準庫對於任何事情都是最理想的。
5. 切記#include 你所用到的功能的頭檔案。
6. 記住,標準庫的功能定義在名字空間std之中。
7. 請用string,而不是char*。
8. 如果懷疑,就用一個檢查區間範圍的向量(例如Vec)。
9. vector 、list和 map 都比T[] 好。
10. 如果向一個容器中添加一個元素,用push_back() 或 back_inserter()。
11. 採用對vector的push_back(),而不是對數組的realloc()。
12. 在main()中捕捉公共的異常。
四、類型和聲明
1. 保持較小的作用域。
2. 不要在一個作用域和它外圍的作用域裡採用同樣的名字。
3. 在一個聲明中只聲明一個名字。
4. 讓常用的和局部的名字比較短,讓不常用的和全局的名字比較長。
5. 避免看起來類似的名字。
6. 維持某種統一的命名風格。
7. 仔細選擇名字,反映其意義而不是反映實現方式。
8. 如果所用的內部類型表示某種可能變化的值,請用typedef 為它定義一個有意義的名字。
9. 用typedef為類型定義同義詞,用枚舉或類去定義新類型。
10. 切記每個聲明中都必須描述一個類型(沒有“隱式的int”)。
11. 避免有關字元數值的不必要假設。
12. 避免有關整數大小的不必要假設。
13. 避免有關浮點類型表示範圍的不必要假設。
14. 優先使用普通的int 而不是short int 或者long int。
15. 優先使用double 而不是float 或者long double。
16. 優先使用普通的 char 而不是 signed char或者 unsigned char。
17. 避免做出有關對象大小的不必要假設。
18. 避免無符號算術。
19. 應該帶著疑問去看待從signed 到unsigned ,或者從unsigned 到signed 的轉換。
20. 應該帶著疑問去看待從浮點到整型的轉換。
21. 應該帶著疑問去看待向較小類型的轉換,如將int轉換到char。
五、忠告
1. 避免非平凡的指針算術。
2. 當心,不要超出數組的界線去寫。
3. 儘量使用0而不是NULL。
4. 儘量使用vector 和valarray ,而不是內部(C風格)的數組。
5. 儘量使用string而不是以0結尾的char 數組。
6. 儘量少用普通的引用參數。
7. 避免 void*,除了在某些底層代碼里。
8. 避免在代碼中使用非平凡的文字量(“神秘的數”)。相反,應該定義和使用各種符號常量。(這裡應理解為避免使用無意義的立即數,而定義一些能夠代表意義的常量,例如,用true而不要用1(C/C++)或-1(VB))