原則:變量定義推遲到真正需要時。減少構造/析構開銷,避免異常拋出時資源浪費,縮小作用域提高可讀性。
// 不好:過早定義 encrypted,若拋出異常則白白構造/析構
string encrypted;
if (password.length() < MIN) throw logic_error("too short");
// ... 使用 encrypted
// 好:需要時才定義
if (password.length() < MIN) throw logic_error("too short");
string encrypted; // 此處定義
// ... 使用 encrypted
// 方式1:循環內定義 (每次構造+析構)
for (int i=0; i
決策依據:若 賦值成本 < 構造+析構成本 且在性能熱點,用方式2;否則優先方式1 (作用域小、異常安全、可維護)。
核心觀點:轉型破壞類型系統,隱藏 Bug,降低可維護性。C++ 四種轉型:
static_cast:編譯期靜態轉型 (相關類型、數值轉換)dynamic_cast:運行期多態轉型 (需 RTTI、有開銷、指針/引用)const_cast:移除 const/volatilereinterpret_cast:底層位模式重解釋 (極危險、不可移植)class Base { ... };
class Derived : public Base { int x; }; // 可能有偏移量
Derived d;
Base* pb = &d; // pb 不一定等於 &d!編譯器可能調整指針值 (加偏移量)
因此永遠不要假設對象佈局,避免基於地址計算的強制轉型。
// 錯誤:轉型創建臨時基類子對象副本!
static_cast (*this).onResize();
// 正確:作用域解析符直接調用
Base::onResize();
// 反模式:dynamic_cast 連環判斷 (慢、脆弱)
for (auto ptr : windows) {
if (auto sw = dynamic_cast(ptr.get())) sw->blink();
else if (auto aw = dynamic_cast(ptr.get())) aw->flash();
}
// 正確:虛函數動態綁定
class Window { public: virtual void blink() {} };
class SpecialWindow : public Window {
void blink() override { /* 閃爍邏輯 */ }
};
for (auto& w : windows) w->blink(); // 一行搞定,擴展性強
原則:將轉型隱藏在工廠函數/虛函數接口後,客戶代碼零轉型。
句柄 = 指針、引用、迭代器。返回內部句柄破壞封裝,導致:
class Rectangle {
Point ul, lr;
public:
Point& upperLeft() const { return ul; } // 返回非 const 引用!
// 調用者可修改:rect.upperLeft().x = 100; // 破壞 const 語義
};
// 修正:返回 const 引用
const Point& upperLeft() const { return ul; }
const Rectangle boundingBox(const GUIObject& obj); // 返回值 (臨時對象)
const Point* p = &boundingBox(*pgo).upperLeft(); // 危險!
// boundingBox 返回臨時 Rectangle,upperLeft() 返回其內部 Point 引用
// 語句結束時臨時對象銷毀,p 成為懸空指針
// 修正:返回值而非引用
Point upperLeft() const { return ul; } // 返回副本,安全
// 或調用者存儲副本
Point p = boundingBox(*pgo).upperLeft();
Inline 本質:請求編譯器將調用點替換為函數體,消除調用開銷,啟用上下文相關優化。但只是請求,非強制。
| 方面 | 收益 | 代價 |
|---|---|---|
| 調用開銷 | 消除壓棧/跳轉/返回指令 | — |
| 優化機會 | 編譯器可內聯後進一步優化 (常量傳播、死代碼消除等) | — |
| 代碼膨脹 | — | 每處調用展開函數體,指令緩存壓力增大,可能反而變慢 |
| 編譯依賴 | — | 頭文件暴露實現,修改實現觸發大量重編譯 |
| 調試困難 | — | 斷點/單步進入行號混亂,調試器支持有限 |
inline。這四項實現細節看似微小,卻體現了 C++ 專家對資源管理、類型安全、封裝完整性、編譯模型的深刻理解。內化為編碼習慣,能寫出更健壯、高效、可維護的 C++ 代碼。