public 繼承表達 is-a(編譯器隱式轉換子類→父類)。private 繼承:
public/protected 成員在子類變為 private。因此 private 繼承表達 is-implemented-in-terms-of(按實現繼承),屬實現細節,非介面設計。
物件組合同樣表達 is-implemented-in-terms-of,且更靈活。優先使用組合,除非:
protected 成員(組合只能存取 public)。virtual 函數(組合無法直接覆寫,需引入內部類繼承)。
// Private 繼承
class Timer { public: virtual void onTick() const; };
class Widget : private Timer {
virtual void onTick() const override { /* 使用 Widget 數據 */ }
};
// 組合 + 內部類 public 繼承
class Widget {
class WidgetTimer : public Timer {
virtual void onTick() const override { /* ... */ }
};
WidgetTimer timer;
};
組合方式可防止 Widget 子類重定義 onTick(C++ 無 final 關鍵字時的替代方案),且降低編譯依賴(WidgetTimer 可前向宣告)。
空類大小 ≥ 1。組合空類會佔用空間(含對齊)。Private 繼承空基類可觸發 EBO,使衍生類大小不增加。STL 中 unary_function 等即為空基類設計。