Effective C++讀書筆記---讓自己習慣C++

導讀
1.做一個有“線程概念”的程序員
一、條款01-視C++爲一個語言聯綁
1.C++是個多重範型的語言(multiparadigm programming language),一個同時支持過程形式(procedural)、面向對象形式(object-oriented)、函數形式(functional)、泛型形式(generic)、元編程形式(metaprogramming)的語言
2.C++並不是一個帶有一組守則的一體語言,它是四個次語言(C/Object-Oriented C++/Template C++/STL)組成的聯綁政府,每個次語言都有自己的規約。C++高效編程守則視狀況而變化,取決於你使用C++的哪一部分
二、條款02-儘量以const/enum/inline替換#define
1.#define不能夠提供任何封裝性
2.有了consts/enums/inlines,我們對預處理器(特別是#define)的需求降低了,但並非完全消除。#include仍然是必需品,而#ifdef/#ifndef也繼續扮演控制編譯的重要

角色。目前還不到預處理器全面引退的時候,但你應該明確地給予它更長更頻繁的假期
3.對於單純常量,最好以const對象或enums替換#define
4.對於形似函數的宏(macros),最好改用inline函數替換#defines。
三、條款03-儘可能使用const
1.char test[] = "hello";
char* p = test;  // non-const pointer, non-const data
const char* p = test; // non-const pointer, const data
char const* p = test; // non const pointer, const data
char* const p = test; // const pointer, non-const data
const char* const p = test; // const pointer, const data
2.令函數返回一個常量值,往往可以降低因客戶錯誤而造成的意外,而又不至於放棄安全性和高效性
3.const成員函數,第一可以使class接口比較容易理解,這是因爲得知哪個函數可以改動對象內容而哪個函數不行,很是重要的。第二,它們使“操作const對象"成爲可能。
4.兩個成員函數如果只是常量性(constness)不同,可以被重載
5.成員函數如果是const,有兩個流行概念:bitwise constness(又稱physical constness)和logical constness
6.const成員函數不可以更改對象內任何non-static成員變量
7.關鍵字mutable可釋放掉non-static成員變量的bitwise constness約束。聲明爲mutable的成員變量可能總會被改變,即使在const成員函數內
8.const是個奇妙且非比尋常的東西。在指針和迭代器身上;在指針、迭代器及reference指涉的對象身上;在函數參數和返回類型身上;在local變量身上;在成員函數身上,林林總總不一而足
9.將某些東西聲明爲const可幫助編譯器偵測出錯誤用法
10.編譯器強制實施bitwise constness,但你編程程序時應該使用"概念上的常量性"(conceptual constness)
11.當const和non-const成員函數有着實質等價的實現時,令non-const版本調用const版本可避免代碼重複[注:不要做反向調用]
四、條款04-確定對象被使用前已被初始化
1.對於無任何成員的內置類型,你必須手工完成初始化。至於內置類型以外的,初始化的責任落在構造函數身上。規則很簡單:確何每一個構造函數都將對象的每一個成員初始化
2.C++規定,對象的成員變量的初始化動作發生在進入構造函數本體之前
3.所以儘量使用初始化列表(member initialization list),而不使用賦值初始化。初始化列表單隻調用一次copy構造,而賦值初始化則要調用一次default構造和一次copy assignment操作符。顯然使用初始化列表是比較高效的
4.C++有着十分固定的“成員初始化次序”。次序總是相同:base classes更早於其derived classes被初始化,而class的成員變量總是以其聲明次序被初始化(即使它們在初始化列表中以不同的次序出現,也不會有任何影響),所以初始化列表最好是其成員變量聲明順序,以免出現晦澀錯誤(是指兩個成員變量的初始化帶有次序性。如初始化array時需要指定大小,因此代表大小的成員變量必須先有初值)
5.C++對“定義於不同的編譯單元(是指產出單一目標文件的那些源碼。基本上它是單一源碼文件加上其所含入的頭文件[#include files])內的non-local static對象”的初始化相對次序並無明確定義。可將non-local static對象般到自己的專屬函數內,變爲local static對象。這些函數返回一個reference指定它所含的對象。然後用戶用這些函數,而不直接指涉這些對象。這也是Design Patterns裏Singleton模式的一個常見手法。這個手法的基礎在於:C++保證,函數內的local static對象會在“該函數被調用期間”“首次遇上該對象之定義式”時被初始化。但是從另一個角度看,這些函數“內含static對象“的事實使它們在多線程系統中帶有不確定性。任何一種non-const static對象,不論它是local或non-local,在多線程環境下“等待某事發生”都會有麻煩。處理這個麻煩的一種做法是:在程序的單線程啓動階段手工調用所有reference-returning函數,這個消除與初始化有關的“競速形勢”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章