Effective C++學習筆記
按孫中山先生的說法,這個世界依聰明才智的先天高下的三種人:先知先覺得發明家,後知後覺的宣傳家,不知不覺的實踐家。三者之中發明家最少最稀珍。
聲明,定義,初始化的差別:
當你看到指派符号時請小心,因為“=”文法也可用來調用copy構造函數:
Widget w3=w2;
幸運的是copy構造很容易和copy指派有所差別。如果一個新對象被定義(例如以上語句中的w3),一定會有個構造函數被調用,不可能調用指派操作。如果沒有新對象被定義,例如 w1 = w2,就不會有構造函數被調用,那麼當然就是指派操作被調用。
1, Accustoming Yourself to C++
條款01:視C++為一個語言聯邦 View C++ as a federation of languages
C++并不是一個帶有一組守則的一體語言;它是從四個次語言組成的聯邦政府,每個次語言都有自己的規約:
n C.說到底C++是以C為基礎的。區塊、語句、預處理、内置資料類型、數組、指針等統統來自C;
n Object_OrientedC++.class,封裝,繼承,多态、virtual函數(動态綁定)….等等;
n Template C++。這是C++的泛型程式設計部分,也是大多數程式員經驗最少的部分。你不必為每一種特定類型都建立一個對象或一個防範;
n STL。STL是個template程式庫,容器、疊代器、算法等。
請記住:
C++高效程式設計守則視狀況而變化,取決于你使用C++的哪一部分。
條款02:盡量以const,enum,inline替換#define。 Preferconsts,enums,and inlines to defines.
這個條款或許可以改為“甯可以編譯器替換預處理器”比較好,因為或許#define不被視為語言的一部分。
我們常以常量替換#defines,有兩種特殊情況:
1,定義常量指針。
const char* const authrname=”Scott Meyers”;
2, class專屬常量,為了確定此常量至多隻有一份時候實體,你必須讓它成為一個static成員:
必須在實作檔案中提供定義;
還可以用enum:
enum的行為較像#define而不想const,枚舉是不占用空間的,編譯器在預處理時會把具體的枚舉值直接填入程式中,可以在VC的彙編視窗檢視, 其實枚舉等于是定義為值的宏而已
另一個常見的#define誤用情況是以它實作宏。宏看起來像函數,但不會招緻函數調用帶來的額外開銷,常用inline來代替
請記住:
對于單純常量,最好以const對象或enums替換#defines。
對于形似函數的宏,最好用Inline函數替換#defines。
條款03:盡可能使用const。Use constwhenever possible.
如果關鍵字const出現在星号左邊,表示被指物是常量;如果出現在星号右邊,表示指針自身是常量;如果出現在星号兩邊,變速被指物和指針兩者都是常量。
Stl疊代器:
前者表示這個疊代器不得指向不用的東西,但它所指的東西的值時可以改動的。如果你希望疊代器所指的東西部可被改動,你需要用const_iterator;
請記住;
n 将某些東西聲明為const可幫助編譯器偵測出錯誤用法;
n 編譯器降至實施bitwise constness;const成員函數不可以更改對象内任何non-static成員變量;
n 當const和non-const成員函數有着實質等級的實作時,令non-const版本調用onst版本可避免代碼重複;
條款04:确定對象被使用前已先被初始化。
確定每一個構造函數都将對象的每一個成員初始化,初始化和指派不同,c++規定,對象的成員變量的初始化動作發生在進入構造函數本體之前。
這個構造函數和上一個的最終結果相同,但通常效率較高。基于指派的那個版本首先調用預設構造函數為三個變量設初值,然後立刻再對它們賦予新值。
如果成員變量是const或references,它們就一定需要初值清單,不能被指派,是以總是使用成員初值列。
C++有着十分固定的“成員初始化次序”。次序總是相同:base classes更早于其derived classes被初始化,而class的成員變量總是以其聲明次序被初始化。
n 請記住:
n 為内置型對象進行手工初始化,因為C++不保證初始化它們。
n 構造函數最好使用成員初值列,而不要在構造函數本體内使用指派操作。初值列列出的成員變量,其排列次序應該和它們在class中的聲明次序相同。
n 為免除“跨編譯單元之初始化次序”問題,請以localstatic對象替換non-localstatic對象。