編寫高質量代碼:改善C++程式的150個建議(囊括編寫高質量C++代碼的技巧、禁忌和最佳實踐)
( 簡體 字) |
作者:李健 | 類別:1. -> 程式設計 -> C++ -> C++ |
譯者: |
出版社:機械工業出版社 | 3dWoo書號: 31740 詢問書籍請說出此書號!【缺書】 NT售價: 295 元 |
出版日:12/9/2011 |
頁數:336 |
光碟數:0 |
|
站長推薦: |
印刷:黑白印刷 | 語系: ( 簡體 版 ) |
|
加入購物車 │加到我的最愛 (請先登入會員) |
ISBN:9787111364092 |
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 序 |
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證) |
作者序: |
譯者序: |
前言:為什么要寫這本書
一直以來,C++就是一門富有爭議的編程語言。一方面它是一門復雜的語言,由于C++語言提供了復雜的語法規則,被看作“拙劣工程學”的成果,甚至引來了Linux之父Linus Benedict Torvalds的炮轟,稱其為“糟糕程序員的垃圾語言”。另一方面它又是一門流行的語言,正如C++之父Stroustrup所說的,“在這12年里,C++用戶數大約每7個半月增加一倍”。雖然有些言過其實,但確實說明了C++的流行程度。在Tiobe編程語言熱度排行榜中,C++穩居前三位,成績斐然(如圖0-1所示)。
圖0-1 Tiobe編程語言排行榜
究其原因,主要在于C++不僅具有面向對象編程語言的邏輯表達優勢,還具有和C語言不相上下的時間效率和空間效率。換言之,C++可以讓我們用清晰的代碼實現高效的程序設計,很好地體現了KISS(Keep It Simple and Stupid)設計之精髓。
C++語言的發展大概可以分為三個階段:
第一階段是從20世紀80年代到1995年。這一階段C++語言基本上是傳統類型上的面向對象語言,并且憑借著接近C語言的運行效率,在工業界使用的開發語言中占據了相當大的份額。
第二階段是從1995年到2000年,在這一階段,由于標準模板庫(STL)和后來的Boost等程序庫的出現,使得泛型程序設計在C++中占據了越來越多的比重。當然,同時由于Java、C#等語言的出現和硬件價格的大規模下降,C++也受到了一定的沖擊。
第三階段是從2000年至今,由于以Loki、MPL等程序庫為代表的產生式編程和模板元編程的出現,C++出現了發展歷史上的又一個新高峰。這些新技術的出現以及和原有技術的融合,使C++成為當今主流程序設計語言中最復雜的一員。
經過多年的技術沉淀,C++在現代軟件領域中已經占據了舉足輕重的地位,特別是在系統級復雜應用程序、高性能并行計算以及對靈活性和底層操作要求較高的軟件開發中占據主導地位和絕對優勢。C++主要應用領域如圖0-2所示。
圖0-2 C++語言主要應用領域
難學易用,可以說是C++語言的最大特點。C++語言具有較高的復雜度和較陡峭的學習曲線。C++語言的“難學”似乎成為了眾多程序員面前的一座“大山”。然而這樣的“大山”并不能成為我們拋棄C++語言的理由,因為大山的后面是我們期望已久的美麗桃花源:C++難學但易用,正如侯捷老師所言:“一旦學成,妙用無窮。”在艱苦的登山途中,一根拐杖會令我們倍感輕松,為廣大聰明而刻苦的C++程序員們提供這樣的一根拐杖便是本書的目的。
對于那些剛剛進入C++世界的程序員來說,別人的經驗教訓就是他的前車之鑒,能夠幫助他快速、準確地掌握C++的要點。為此,我將自己和前輩們的“工程經驗”進行總結、歸納、升華,最后整理成150條意見和建議,以期幫助大家更好地理解、運用C++語言。
讀者對象
本書適用于具有一定C/C++語言基礎的程序員。書中的150條建議能夠幫助讀者更加深入地理解C++語言,用好C++語言,提升C++程序設計的整體品質。
如何閱讀本書
作為一個C++從業者,我十分了解初學者在學習過程中可能遇到的困惑,清楚那些“工程經驗的積累”對一個初學者成長的顯著作用。所以,本書采用了《Effective C++》經典的“條款式”敘述方式,對本人以及眾多C++前輩們的經驗進行了重新的編撰整理,總結成了150條編程建議。
本書所包括的150條編程建議,可以說是散布在各個角落的語言規則、編程準則,以及最佳實踐的匯總;這150條建議將分為三大部分:語法篇、編碼習慣和規范篇、程序架構和思想篇。這三大部分從語言語法,到編碼習慣,再到架構思想,由淺入深,層層遞進,使讀者逐漸認識并理解這門語言。
其中,語法篇主要圍繞語法展開,分為從C繼承而來的、從C到C++的改變、內存管理、類、模板、異常處理、STL七章;編碼習慣和規范篇則集中在“習慣”二字上,建議主要集中在如何提高程序的正確性、可讀性、效率等方面;而最后的程序架構和思想篇,則站在更高的高度去審視程序設計,給出一些編程規范和最佳實踐。
我希望本書中的每條建議都能引起讀者的思考,鼓勵消化理解,杜絕死記硬背,取其精華去其糟粕;我希望本書中的每條建議所傳遞的理念能夠滲透到讀者的設計實踐中,而不是邯鄲學步式地模仿,使這些建議成為編寫程序的束縛。
勘誤和支持
由于作者水平有限,編寫時間倉促,書中難免會出現一些錯誤、疏漏或者不妥之處,懇請讀者批評指正。你可以將書中的錯誤通過郵件告知我,也可以將你遇到的其他問題通過郵件發給我,我將盡力提供最滿意的解答。我的郵箱是lijian8409@gmail.com,真誠期待大家的反饋。
致謝
感謝偉大的Bjarne Stroustrup博士,是他發明了C++這樣一門影響深遠的語言;感謝為C++語言做出重大貢獻的前輩們,是你們的努力讓C++語言不斷向前發展。
感謝機械工業出版社華章公司的楊福川編輯和楊繡國編輯,是你們一直以來的支持與幫助促進了這本書的順利出版。
感謝遠在家鄉的父母,你們二十余年如一日的關愛和鼓勵,是我面對困難和挫折時重新振作的力量源泉,讓我不敢懈怠,不言放棄;感謝仍在繼續學業的弟弟,希望你能順利拿到博士學位,實現你的理想與人生價值;感謝親愛的老婆的默默陪伴和支持,你是我前進的最大動力。對你們的愛永存心間。
謹以此書,獻給我深愛的家人,以及眾多熱愛并奮斗在C++第一線的朋友們。
李 健
2011年10月于北京 |
內容簡介:本書是C++程序員進階修煉的必讀之作,包含的全部都是C++編碼的最佳實踐,從語法、編碼規范和編程習慣、程序架構和設計思想等三大方面對C++程序和設計中的疑難問題給出了經驗性的解決方案,為C++程序員編寫更高質量的C++代碼提供了150條極為寶貴的建議。每個問題都來自于實踐,都極具代表性,本書不僅以建議的方式正面為每個問題給出了被實踐證明為十分優秀的解決方案,而且還從反面給出了被實踐證明為不好的解決方案,從正反兩個方面進行了分析和對比。
全書在邏輯上一共分為三個部分:語法部分涵蓋C++從C語言繼承而來的一些極為重要但又極容易被誤解和誤用的一些語法特性,從C語言到C++的改變,以及內存管理、類、模板、異常處理、STL等方面的內容;編碼習慣和編程規范部分則主要討論了如何提高程序的正確性、可讀性、程序性能和編碼效率方面的問題;程序架構和思想部分則從更高的高度對C++程序設計思維和方法進行了審視,給出了一些頗具價值的觀點和最佳實踐。
這是一本關于如何提高C++程序設計效率與質量的工具書,希望書中的每條建議都能引起你的思考,對于有難度的內容,建議大家消化理解,切勿死記硬背,同時也希望大家能悟出更好的解決方案。希望本書中的每條建議所傳遞的思想和理念能夠滲透到大家的編碼實踐中,進而幫助大家真正具備編寫高質量C++代碼的能力。 |
目錄:前 言
第一部分 語法篇
第1章 從C繼承而來的/2
建議0:不要讓main函數返回void/2
建議1:區分0的4種面孔/5
建議2:避免那些由運算符引發的混亂/8
建議3:對表達式計算順序不要想當然/9
建議4:小心宏#define使用中的陷阱/12
建議5:不要忘記指針變量的初始化/14
建議6:明晰逗號分隔表達式的奇怪之處/15
建議7:時刻提防內存溢出/16
建議8:拒絕晦澀難懂的函數指針/19
建議9:防止重復包含頭文件/19
建議10:優化結構體中元素的布局/21
建議11:將強制轉型減到最少/23
建議12:優先使用前綴操作符/26
建議13:掌握變量定義的位置與時機/28
建議14:小心typedef使用中的陷阱/30
建議15:盡量不要使用可變參數/32
建議16:慎用goto/36
建議17:提防隱式轉換帶來的麻煩/38
建議18:正確區分void與void*/42
第2章 從C到C++,需要做出一些改變/45
建議19:明白在C++中如何使用C /45
建議20:使用memcpy()系列函數時要足夠小心/48
建議21:盡量用new/delete代替malloc/free/49
建議22:靈活地使用不同風格的注釋/52
建議23:盡量使用C++標準的iostream/55
建議24:盡量采用C++風格的強制轉型/58
建議25:盡量用const、enum、inline替換#define/59
建議26:用引用代替指針/62
第3章 說一說“內存管理”的那點事兒/66
建議27:區分內存分配的方式/67
建議28:new/delete與new[]/delete[]必須配對使用/69
建議29:區分new的三種形態/71
建議30:new內存失敗后的正確處理/75
建議31:了解new_handler的所作所為/78
建議32:借助工具監測內存泄漏問題/81
建議33:小心翼翼地重載operator new/ operator delete /84
建議34:用智能指針管理通過new創建的對象/88
建議35:使用內存池技術提高內存申請效率與性能/91
第4章 重中之重的類/95
建議36:明晰class與struct之間的區別/95
建議37:了解C++悄悄做的那些事/99
建議38:首選初始化列表實現類成員的初始化/101
建議39:明智地拒絕對象的復制操作/105
建議40:小心,自定義拷貝函數/107
建議41:謹防因構造函數拋出異常而引發的問題/110
建議42:多態基類的析構函數應該為虛/113
建議43:絕不讓構造函數為虛/116
建議44:避免在構造/析構函數中調用虛函數/117
建議45:默認參數在構造函數中給你帶來的喜與悲/120
建議46:區分Overloading、Overriding及Hiding之間的差異/122
建議47:重載operator=的標準三步走/126
建議48:運算符重載,是成員函數還是友元函數/131
建議49:有些運算符應該成對實現/134
建議50:特殊的自增自減運算符重載/136
建議51:不要重載operator&&、operator||以及operator,/137
建議52:合理地使用inline函數來提高效率/139
建議53:慎用私有繼承/141
建議54:抵制MI的糖衣炮彈/144
建議55:提防對象切片/147
建議56:在正確的場合使用恰當的特性/150
建議57:將數據成員聲明為private/154
建議58:明晰對象構造與析構的順序/156
建議59:明了如何在主調函數啟動前調用函數/158
第5章 用好模板,向著GP開進/161
建議60:審慎地在動、靜多態之間選擇/161
建議61:將模板的聲明和定義放置在同一個頭文件里/164
建議62:用模板替代參數化的宏函數/168
建議63:區分函數模板與模板函數、類模板與模板類/169
建議64:區分繼承與模板/171
第6章 讓神秘的異常處理不再神秘/176
建議65:使用exception來處理錯誤/176
建議66:傳值throw異常,傳引用catch異常/179
建議67:用“throw;”來重新拋出異常/183
建議68:了解異常捕獲與函數參數傳遞之間的差異/185
建議69:熟悉異常處理的代價/189
建議70:盡量保證異常安全/192
第7章 用好STL這個大輪子/198
建議71:盡量熟悉C++標準庫/198
建議72:熟悉STL中的有關術語/201
建議73:刪除指針的容器時避免資源泄漏/204
建議74:選擇合適的STL容器/206
建議75:不要在STL容器中存儲auto_ptr對象/209
建議76:熟悉刪除STL容器中元素的慣用法/210
建議77:小心迭代器的失效/213
建議78:盡量使用vector和string代替動態分配數組/214
建議79:掌握vector和string與C語言API的通信方式/216
建議80:多用算法調用,少用手寫循環/217
第二部分 編碼習慣和規范篇
第8章 讓程序正確執行/222
建議81:避免無意中的內部數據裸露/222
建議82:積極使用const為函數保駕護航/224
建議83:不要返回局部變量的引用/228
建議84:切忌過度使用傳引用代替傳對象/230
建議85:了解指針參數傳遞內存中的玄機/231
建議86:不要將函數參數作為工作變量 /233
建議87:躲過0值比較的層層陷阱/234
建議88:不要用reinterpret_cast去迷惑編譯器/236
建議89:避免對動態對象指針使用static_cast/237
建議90:盡量少應用多態性數組/238
建議91:不要強制去除變量的const屬性/240
第9章 提高代碼的可讀性/242
建議92:盡量使代碼版面整潔優雅/243
建議93:給函數和變量起一個“能說話”的名字/246
建議94:合理地添加注釋/248
建議95:為源代碼設置一定的目錄結構/251
建議96:用有意義的標識代替Magic Numbers/252
建議97:避免使用“聰明的技巧”/253
建議98:運算符重載時堅持其通用的含義/254
建議99:避免嵌套過深與函數過長/255
建議100:養成好習慣,從現在做起/256
第10章 讓代碼運行得再快些/258
建議101:用移位實現乘除法運算/258
建議102:優化循環,提高效率/259
建議103:改造switch語句/260
建議104:精簡函數參數 /261
建議105:謹慎使用內嵌匯編/262
建議106:努力減少內存碎片/263
建議107:正確地使用內聯函數/263
建議108:用初始化取代賦值/264
建議109:盡可能地減少臨時對象/266
建議110:最后再去優化代碼/267
第11章 零碎但重要的其他建議/269
建議111:采用相對路徑包含頭文件/269
建議112:讓條件編譯為開發出力/270
建議113:使用.inl文件讓代碼整潔可讀/272
建議114:使用斷言來發現軟件問題/274
建議115:優先選擇編譯和鏈接錯誤/275
建議116:不放過任何一條編譯器警告/277
建議117:盡量減少文件之間的編譯依賴 /278
建議118:不要在頭文件中使用using/280
建議119:劃分全局名空間避免名污染/282
第三部分 程序架構和思想篇
第12章 面向對象的類設計/286
建議120:堅持“以行為為中心”的類設計/286
建議121:用心做好類設計/287
建議122:以指針代替嵌入對象或引用/289
建議123:努力將接口最小化且功能完善/291
建議124:讓類的數據隱藏起來/292
建議125:不要讓成員函數破壞類的封裝性/294
建議126:理解“virtual + 訪問限定符”的深層含義/295
建議127:謹慎恰當地使用友元機制/297
建議128:控制對象的創建方式/299
建議129:控制實例化對象的個數/301
建議130:區分繼承與組合/303
建議131:不要將對象的繼承關系擴展至對象容器/307
建議132:杜絕不良繼承/308
建議133:將RAII作為一種習慣/310
建議134:學習使用設計模式/311
建議135:在接口繼承和實現繼承中做謹慎選擇/314
建議136:遵循類設計的五項基本原則/315
第13章 返璞歸真的程序設計/318
建議137:用表驅動取代冗長的邏輯選擇/318
建議138:為應用設定特性集/324
建議139:編碼之前需三思/324
建議140:重構代碼/326
建議141:透過表面的語法挖掘背后的語義/328
建議142:在未來時態下開發C++程序/330
建議143:根據你的目的決定造不造輪子/331
建議144:謹慎在OO與GP之間選擇/331
建議145:讓內存管理理念與時俱進/332
建議146:從大師的代碼中學習編程思想與技藝/334
建議147:遵循自然而然的C++風格/335
建議148:了解C++語言的設計目標與原則/335
建議149:明確選擇C++的理由/338 |
序: |