核心:「寧用編譯器,勿用預處理器」。
#define 無作用域、無類型、調試符號表不可見。
const 有類型、有作用域、進入符號表。
inline 函數類型安全、可調試、避免函數調用開銷。
例外:#include、#ifdef/#ifndef 仍不可替代。
原因:初始化列表直接構造,賦值則「默認構造 + 再賦值」雙重開銷。
必須用初始化列表:const 成員、引用成員、無默認構造的基類/成員。
注意:static 成員不在列表中初始化,單獨在類外定義初始化。
C++ 默認傳值 → 調用拷貝構造函數,開銷大。
傳引用 避免拷貝,但引入別名問題(條款 17)。
例外:內置類型(int、指針)、STL 迭代器/函數對象——傳值更高效。
痛點:大型專案全局符號衝突。
方案:命名空間隔離模組、庫、子系統。編譯器支持後盡早遷移真正 namespace,而非靠前綴模擬。
C 習慣:函數開頭集中定義。
C++ 現實:定義即構造,析構即銷毀。無用定義 = 無用構造/析構開銷。
收益:效率↑、作用域↓、可讀性↑、註釋需求↓。
手段:
① 前置聲明替換 #include
② 依賴聲明而非定義(接口類、Pimpl 慣用語)
③ 盡量不在頭文件定義 inline/模板實現
目標:修改實現不觸發大規模重編譯。
Effective C++ 不僅是規則手冊,更是 C++ 物件模型與編譯模型 的深度思考。
每條款背後都是「為什麼語言這樣設計」與「如何不踩坑」的工程智慧。