# Item 1: 將 C++ 視為 federation of languages(語言聯合體)
作者:Scott Meyers
譯者:fatalerror99 (iTePub's Nirvana)
發布:http://blog.csdn.net/fatalerror99/
最初,C++ 僅僅是在 C 的基礎上附加了一些 object-oriented(面向對象)的特性。C++ 最初的名稱—— "C with Classes" 就非常直觀地表現了這一點。
作為一個語言的成熟過程,C++ 的成長大膽而充滿冒險,它吸收的思想,特性,以至于編程策略與 C with Classes 越來越不同。exceptions(異常)要求不同的建構功能的途徑(參見 Item 29),templates(模板)將設計思想提升到新的高度(參見 Item 41),而 STL 定義了一條前所未見的通向擴展性的道路。
今天的 C++ 已經成為一個 multiparadigm programming language(多范式的編程語言),一個囊括了 procedural(過程化),object-oriented(面向對象),functional(函數化),generic(泛型)以及 metaprogramming(元編程)特性的聯合體。這些能力和彈性使 C++ 成為無可匹敵的工具,但也引起了一些混亂。所有的 "proper usage"(慣用法)規則似乎都有例外。我們該如何認識這樣一個語言?
最簡單的方法是不要將 C++ 視為一個單一的語言,而是一個親族的語言的 federation(聯合體)。在每一個特定的 sublanguage(子語言)中,它的特性趨向于直截了當,簡單易記。但你從一個 sublanguage(子語言)轉到另外一個,它的規則也許會發生變化。為了感受 C++,你必須將它的主要的 sublanguages(子語言)組織到一起。幸運的是,它只有 4 個:
* C ——歸根結底,C++ 依然是基于 C 的。blocks(模塊),statements(語句),preprocessor(預處理器),built-in data types(內建數據類型),arrays(數組),pointers(指針)等等,全都來自于 C。在很多方面。C++ 提出了比相應的 C 版本更高級的解決問題的方法(例如,參見 Item 2(選擇 preprocessor(預處理器))和 13(使用 objects(對象)管理 resources(資源))),但是,當你發現你自己工作在 C++ 的 C 部分時,effective programming(高效編程)的規則表現了 C 的諸多限制范圍:沒有 templates(模板),沒有 exceptions(異常),沒有 overloading(重載)等等。
* Object-Oriented C++ —— C++ 的這部分就是 C with Classes 涉及到的全部:classes(類)(包括構造函數和析構函數),encapsulation(封裝),inheritance(繼承),polymorphism(多態),virtual functions (dynamic binding)(虛擬函數(動態綁定))等。C++ 的這一部分直接適用于 object-oriented design(面向對象設計)的經典規則。
* Template C++ ——這是 C++ 的 generic programming(泛型編程)部分,大多數程序員對此都缺乏經驗。template(模板)的考慮已遍及 C++,而且好的編程規則中包含特殊的 template-only(模板專用)條款已不再不同尋常(參見 Item 46 通過調用 template functions(模板函數)簡化 type conversions(類型轉換))。實際上,templates(模板)極為強大,它提供了一種全新的 programming paradigm(編程范式)—— template metaprogramming (TMP) (模板元編程)。Item 48 提供了一個 TMP 的概述,但是,除非你是一個 hard-core template junkie(死心塌地的模板癮君子),否則你不需在此費心,TMP 的規則對主流的 C++ 編程少有影響。
* STL —— STL 是一個 template library(模板庫),但它一個非常特殊的 template library(模板庫)。它將 containers(容器),iterators(迭代器),algorithms(算法)和 function objects(函數對象)非常優雅地整合在一起,但是。templates(模板)和 libraries(庫)也可以圍繞其它的想法建立起來。STL 有很多獨特的處事方法,當你和 STL 一起工作,你需要遵循它的規則。
在頭腦中保持這四種 sublanguages(子語言),當你從一種 sublanguage(子語言)轉到另一種時,為了高效編程你需要改變你的策略,不要吃驚你遭遇到的情景。例如,使用 built-in(內建)(也就是說,C-like(類 C 的))類型時,pass-by-value(傳值)通常比 pass-by-reference(傳引用)更高效,但是當你從 C++ 的 C 部分轉到 Object-Oriented C++(面向對象 C++),user-defined constructors(用戶自定義構造函數)和 destructors(析構函數)意味著,通常情況下,更好的做法是 pass-by-reference-to-const(傳引用給 const)。在 Template C++ 中工作時,這一點更加重要,因為,在這種情況下,你甚至不知道你的操作涉及到的 object(對象)的類型。然而,當你進入 STL,你知道 iterators(迭代器)和 function objects(函數對象)以 C 的 pointers(指針)為原型,對于 STL 中的 iterators(迭代器)和 function objects(函數對象),古老的 C 中的 pass-by-value(傳值)規則又重新生效。(關于選擇 parameter-passing(參數傳遞)方式的全部細節,參見 Item 20。)
C++ 不是使用一套規則的單一語言,而是 federation of four sublanguages(四種子語言的聯合體),每一種都有各自的規則。在頭腦中保持這些 sublanguages(子語言),你會發現對 C++ 的理解會容易得多。
Things to Remember
* effective C++ programming(高效 C++ 編程)規則的變化,依賴于你使用 C++ 的哪一個部分。
- Preface(前言)
- Introduction(導言)
- Terminology(術語)
- Item 1: 將 C++ 視為 federation of languages(語言聯合體)
- Item 2: 用 consts, enums 和 inlines 取代 #defines
- Item 3: 只要可能就用 const
- Item 4: 確保 objects(對象)在使用前被初始化
- Item 5: 了解 C++ 為你偷偷地加上和調用了什么函數
- Item 6: 如果你不想使用 compiler-generated functions(編譯器生成函數),就明確拒絕
- Item 7: 在 polymorphic base classes(多態基類)中將 destructors(析構函數)聲明為 virtual(虛擬)
- Item 8: 防止因為 exceptions(異常)而離開 destructors(析構函數)
- Item 9: 絕不要在 construction(構造)或 destruction(析構)期間調用 virtual functions(虛擬函數)
- Item 10: 讓 assignment operators(賦值運算符)返回一個 reference to *this(引向 *this 的引用)
- Item 11: 在 operator= 中處理 assignment to self(自賦值)
- Item 12: 拷貝一個對象的所有組成部分
- Item 13: 使用對象管理資源
- Item 14: 謹慎考慮資源管理類的拷貝行為
- Item 15: 在資源管理類中準備訪問裸資源(raw resources)
- Item 16: 使用相同形式的 new 和 delete
- Item 17: 在一個獨立的語句中將 new 出來的對象存入智能指針
- Item 18: 使接口易于正確使用,而難以錯誤使用
- Item 19: 視類設計為類型設計
- Item 20: 用 pass-by-reference-to-const(傳引用給 const)取代 pass-by-value(傳值)
- Item 21: 當你必須返回一個對象時不要試圖返回一個引用
- Item 22: 將數據成員聲明為 private
- Item 23: 用非成員非友元函數取代成員函數
- Item 24: 當類型轉換應該用于所有參數時,聲明為非成員函數
- Item 25: 考慮支持不拋異常的 swap
- Item 26: 只要有可能就推遲變量定義
- Item 27: 將強制轉型減到最少
- Item 28: 避免返回對象內部構件的“句柄”
- Item 29: 爭取異常安全(exception-safe)的代碼
- Item 30: 理解 inline 化的介入和排除
- Item 31: 最小化文件之間的編譯依賴
- Item 32: 確保 public inheritance 模擬 "is-a"
- Item 33: 避免覆蓋(hiding)“通過繼承得到的名字”
- Item 34: 區分 inheritance of interface(接口繼承)和 inheritance of implementation(實現繼承)
- Item 35: 考慮可選的 virtual functions(虛擬函數)的替代方法
- Item 36: 絕不要重定義一個 inherited non-virtual function(通過繼承得到的非虛擬函數)
- Item 37: 絕不要重定義一個函數的 inherited default parameter value(通過繼承得到的缺省參數值)
- Item 38: 通過 composition(復合)模擬 "has-a"(有一個)或 "is-implemented-in-terms-of"(是根據……實現的)
- Item 39: 謹慎使用 private inheritance(私有繼承)
- Item 40: 謹慎使用 multiple inheritance(多繼承)
- Item 41: 理解 implicit interfaces(隱式接口)和 compile-time polymorphism(編譯期多態)
- Item 42: 理解 typename 的兩個含義
- Item 43: 了解如何訪問 templatized base classes(模板化基類)中的名字
- Item 44: 從 templates(模板)中分離出 parameter-independent(參數無關)的代碼
- Item 45: 用 member function templates(成員函數模板) 接受 "all compatible types"(“所有兼容類型”)
- Item 46: 需要 type conversions(類型轉換)時在 templates(模板)內定義 non-member functions(非成員函數)
- Item 47: 為類型信息使用 traits classes(特征類)
- Item 48: 感受 template metaprogramming(模板元編程)
- Item 49: 了解 new-handler 的行為
- Item 50: 領會何時替換 new 和 delete 才有意義
- Item 51: 編寫 new 和 delete 時要遵守慣例
- Item 52: 如果編寫了 placement new,就要編寫 placement delete
- 附錄 A. 超越 Effective C++
- 附錄 B. 第二和第三版之間的 Item 映射