Effective cpp 讀書筆記1

本週內,每天更新。

01.視C++爲一個語言聯邦

  1. C++的特性主要來源四個大方面(四個次語言)

    • 以C爲基礎

    • Object-oriented C++:面向類的思想,包括封裝、繼承、多態

    • Template C++:

    • 模板類 STL

  2. 結論:

    • C++高效編程守則視狀況而變化,取決於你用C++的哪部分

02.儘量以const,enum,inline替換#define

  1. 壞處

    • define不被視爲語言的一部分,在預編譯的時候可能就被對應數據和字符取代,編譯器看不到相關的記號

    • 宏定義的函數存在非安全性

  2. 用const取代

    • 定義常量指針:注意const的放置

    • class專屬常量:可以聲明的同時初始化;也可以在實現文件內初始化

  3. 用enum取代

    • 無法取對應的地址(#define也得到,功能相似)

    • 不想別人獲得pointer或reference指向該資源

  4. 用inline取代

    • 某些時候,宏定義的函數不安全,可以用template inline的函數取代;因爲inline的函數也相當於內部直接插入一段代碼
  5. 結論:

    • 對於單純常量,最好以const對象或enums替換#defines

    • 對於形如函數的宏,最好改用inline函數替換


03.儘可能使用const

  1. 注意:

    • const出現在型號左邊,表示被指物是常量;在右邊表示指針自身是常量

    • STL的靜態指針: const std::vector::iterator 表示指針自身是常量,不能++;std::vector::const_iterator 表示被指物是常量

  2. const成員函數

    • 是爲了確認該成員函數可作用於const對象身上

    • 真實程序中,const大多用於passed by pointer-to-const或passed by reference-to-const

  3. bitwise constness(編譯器就是這種)和logical constness:

    • bitwise constness是成員函數只有在不更改對象的任何成員變量時就認爲是符合const,這個定義存在一定不足,因爲即使編譯器查不出更改也可能存在更改

    • logical constness是一個const成員可以修改它所處對象內的某些bits,但只有在客戶端偵測不出的情況下纔可以

    • 通過mutable關鍵字,可以釋放掉non-static成員變量的bitwise constness約束,從而在const函數內也可以修改所在對象的mutable成員變量

  4. 在const和non-const成員函數中避免重複

    • 實現常量性轉除。消除const的性質,具體的做法是在non-const的函數裏調用對應的const函數,並實現強制轉換(const_cast可以強制消除const屬性,static_cast可以實現強制轉換)
  5. 結論:

    • 將某些東西聲明爲const可幫助編譯器真測出錯誤用法編譯器強制實施bitwise constness, 但編程應該使用“概念常量性”(具體問題具體分析,編譯器不可靠的意思)

    • 當const和non-const成員函數存在等價實現,用non-const函數調用const版本可以避免代碼重複


04.確定對象被使用前已先初始化

  1. 手工初始化:

    • 對於無任何成員的內置類型,需要手工初始化
  2. 構造函數最好使用成員初值列,而不要在構造函數內賦值操作。初值列列出的成語變量,其排列次序應該和它們在class中的聲明次序相同

    • 要區分賦值和初始化,對於class的對象,在構造函數內賦值實際上是先調用了它們的默認構造函數,然後做賦值操作,比較低效

    • 成員的初始化列表本質是調用複製構造函數,效率較高

    • 規則:總是在初值列中列出所有成員變量,以免還需記住那些成員變量無需初值

  3. 爲了免除“跨編譯單元之初始化次序”的問題(就是定義文件之間的初始化沒有先後順序),應該以local static對象替換non-local static對象

    • non-local static:函數外的static對象就是non-local static變量

    • 編譯單元:產出單一目標文件的源碼,基本上它是單一源碼文件加上其所含的頭文件

    • 問題:C++對於不同編譯單元內的non-local static對象的初始化次序沒有明確定義

    • 解決:用singleton的思想。將每個non-local static變量搬到專屬函數內,這些函數返回一個reference指向它所含的對象,然後用戶調用這些函數,不直接調用對象。這時,non-local static變成了local static

    • 這種reference-returning函數的形式:定義並初始化一個local static, 然後返回它

發佈了33 篇原創文章 · 獲贊 21 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章