面向物件三大特性:封裝、繼承、多態。多態是實現擴展性與解耦的關鍵。本文深入剖析動態多態(Dynamic Polymorphism)與靜態多態(Static Polymorphism)的實現原理、優劣勢對比、適用場景與工程決策指引。
class Circle {
public:
void Draw() const { cout << "Circle Draw" << endl; }
};
class Line {
public:
void Draw() const { cout << "Line Draw" << endl; }
};
template
void DrawGeoObj(T const & obj) {
obj.Draw(); // 編譯期實例化,靜態綁定
}
int main() {
Circle c1; Line l1;
DrawGeoObj(c1); // 實例化 DrawGeoObj
DrawGeoObj(l1); // 實例化 DrawGeoObj
}
抽象層持有實作介面指針,運行期可動態切換實作。結構較重,需虛函數調用開銷。
template
class Interface {
private:
Implementation body;
public:
// 透傳介面...
};
編譯期確定實作型別,零開銷抽象,但無法運行期切換實作。
| 維度 | 動態多態 | 靜態多態 |
|---|---|---|
| 型別安全 | 運行期檢查(dynamic_cast) | 編譯期強檢查,更安全 |
| 執行效能 | 虛函數間接調用開銷 | 內聯優化,零抽象開銷 |
| 代碼膨脹 | 單一代碼段 | 模板實例化可能膨脹 |
| 異構集合 | 支援(基類指針容器) | 不支援 |
| 運行期切換 | 支援 | 不支援 |
| 編譯依賴 | 僅需基類宣告 | 需完整模板定義(頭文件) |
| 二進制相容 | 良好(介面穩定) | 差(模板變更需重編譯) |
需要運行期根據配置/輸入切換行為?
├─ 是 → 動態多態(或策略模式+工廠)
└─ 否 → 行為在編譯期已知?
├─ 是 → 靜態多態(CRTP、模板策略、概念)
└─ 否 → 混合方案:動態多態外層 + 靜態多態內層
動態多態與靜態多態非對立關係,而是解決不同維度問題的工具。現代 C++(C++17/20)以 Concepts、constexpr、if constexpr、std::variant、std::visit 等特性模糊了邊界,賦予開發者「按需選擇綁定時機」的自由。掌握兩者本質,才能在架構設計中做出最優權衡。