條款 1:儘可能用 const 和 inline 而不用#defineios
#define 用 const ,inline程序員
template<class T>函數
inline const T& max(const T& a, const T& b) { return a > b ? a : b; }性能
<iostream>this
條款 2:儘可能用<iostream>而不用<stdio.h>指針
條款 3:儘可能用 new 和 delete 而不用 malloc 和 free對象
條款 4:儘可能使用 C++風格的註釋繼承
#define LIGHT_SPEED 3e8 // m/sec (in a vacuum)接口
行尾的註釋居然成爲了宏的一部分!內存
內存管理:正確地獲得它和有效地使用它。
條款 5:對應的 new 和 delete 要採用相同的形式
條款 6:析構函數裏對指針成員調用 delete
條款 7:預先準備好內存不夠的狀況 set_new_handler
條款 8. 寫 operator new 和 operator delete 時要遵循常規
返回值的部分很簡單。若是內存分配請求成功,就返回指向內存的指針;
若是失敗,則遵循條款 7 的規定拋出一個 std::bad_alloc 類型的異常。
條款 9. 避免隱藏標準形式的 new
條款 10. 若是寫了 operator new 就要同時寫 operator delete
內存泄露的緣由在於內存分配後指向內存的指針丟失了。
內存池
自定義的內存管理程序能夠很好地改善程序的性能
構造函數控制對象 生成時的基本操做,並保證對象被初始化;析構函數摧毀一個對象並保證它被 完全清除;
條款 11: 爲須要動態分配內存的類聲明一個拷貝構造函數和一個賦值操做符
a: data——> "Hello\0" b: data——> "World\0"
b = a;
第一,b 曾指向的內存永遠不會被刪除,於是會 永遠丟失。這是產生內存泄漏的典型例子。第二,如今 a 和 b 包含的指針指向 同一個字符串,那麼只要其中一個離開了它的生存空間,其析構函數就會刪除 掉另外一個指針還指向的那塊內存。
用 delete 去刪除一個已經被刪除的指針,其結果是不可預測的。
解決這類指針混亂問題的方案在於,只要類裏有指針時,就要寫本身版本 的拷貝構造函數和賦值操做符函數。
條款 12: 儘可能使用初始化而不要在構造函數裏賦值
template<class T>
NamedPtr<T>::NamedPtr(const string& initName, T *initPtr ) : name(initName), ptr(initPtr)
{}
template<class T>
NamedPtr<T>::NamedPtr(const string& initName, T *initPtr) {
name = initName;
ptr = initPtr; }
const 成員只能被初始化,不能被賦值。
條款 13: 初始化列表中成員列出的順序和它們在類中聲明的順序相同
若是想弄清楚對象被初始化時究竟是怎麼作的,請確信你 的初始化列表中成員列出的順序和成員在類內聲明的順序一致。
條款 14: 肯定基類有虛析構函數
一個類想跟蹤它有多少個對象存在。一個簡單的方法是建立一個靜 態類成員來統計對象的個數。這個成員被初始化爲 0,在構造函數里加 1,析 構函數裏減 1。
當且僅當類裏包含至少一個虛函數的時候纔去聲明 虛析構函數。
條款 15: 讓 operator=返回*this 的引用
一個錯誤是讓 operator=返回 void
另外一個常犯的錯誤是讓operator=返回一個const對象的引用
條款 16: 在 operator=中對全部數據成員賦值
條款 17: 在 operator=中檢查給本身賦值的狀況
條款 18: 爭取使類的接口完整而且最小
類的用戶接口是指使用這個類的程序員所能訪問獲得的接口。
條款 19: 分清成員函數,非成員函數和友元函數
條款 20: 避免 public 接口出現數據成員
條款 21: 儘量使用 const
條款 22: 儘可能用「傳引用」而不用「傳值」
爲避免這種潛在的昂貴的開銷,就不要經過值來傳遞對象
條款 23: 必須返回一個對象時不要試圖返回一個引用
條款 24: 在函數重載和設定參數缺省值間慎重選擇
條款 25: 避免對指針和數字類型重載
void f(int x);
void f(string *ps);
f(0); // 調用 f(int)仍是 f(string*)?
條款 26: 小心潛在的二義性
條款 27: 若是不想使用隱式生成的函數就要顯式地禁止它
條款 28: 劃分全局名字空間
條款 29: 避免返回內部數據的句柄
條款 31: 千萬不要返回局部對象的引用,也不要返回函數內部用 new 初始化的 指針的引用
條款 33: 明智地使用內聯
條款 34: 將文件間的編譯依賴性降至最低
條款 35: 使公有繼承體現 "是一個" 的含義
寫下類 D("Derived" )從類 B("Base")公有繼承時,你其實是在告 訴編譯器(以及讀這段代碼的人):類型 D 的每個對象也是類型 B 的一個對 象,但反之不成立;
條款 36: 區分接口繼承和實現繼承
定義純虛函數的目的在於,使派生類僅僅只是繼承函數的接口。
條款 37: 決不要從新定義繼承而來的非虛函數
條款 38: 決不要從新定義繼承而來的缺省參數值
缺省參數值要相同
虛函數是動態綁定的:虛函數經過哪一個對象被調用,具體被調,用的函數就由那個對象的動態類型決定:
條款 39: 避免 "向下轉換" 繼承層次
從一個基類指針到一個派生類指針 ---- 被稱爲 "向下 轉換"
條款 40: 經過分層來體現 "有一個" 或 "用...來實現"
條款 41: 區分繼承和模板
條款 42: 明智地使用私有繼承
條款 43: 明智地使用多繼承
條款 44: 說你想說的;理解你所說的
條款 45: 弄清 C++在幕後爲你所寫、所調用的函數
條款 46: 寧肯編譯和連接時出錯,也不要運行時出錯
條款 47: 確保非局部靜態對象在使用前被初始化
條款 48: 重視編譯器警告
條款 49: 熟悉標準庫
條款 50: 提升對 C++的認識