一年多前面試某印度公司的 C++ 職位,被問到 virtual base class。雖然耳熟能詳,卻說不出所以然。回家翻書才恍然大悟,特此整理記錄,以免再忘——致敬《馬語者》「以免你忘記」。
| 概念 | C++ | C# |
|---|---|---|
| 虛擬方法 | virtual 關鍵字 | virtual 關鍵字 |
| 純虛擬方法(無實作) | virtual void Foo() = 0; | abstract void Foo(); |
| 抽象類別 | 包含純虛擬函數的類別(abstract 非關鍵字) | abstract class 關鍵字 |
| 介面 | 無原生支援(用純抽象類別模擬) | interface 關鍵字 |
class A { /* 基類 */ };
class B : virtual public A { }; // 虛擬繼承
class C : virtual public A { };
class D : public B, public C { }; // D 中只有一份 A
虛擬繼承確保最衍生類別中基類只有一份實例,避免資料重複與二義性。
C++ 中 abstract 僅是慣稱,非語言關鍵字。任何含有 =0 純虛擬函數的類別即為抽象類別,不可實例化。
C++ 中所有多態相關聲明皆由 virtual 一手包辦。C# 引入 interface 與 abstract 後,virtual 職責大幅縮減:僅用於標示「可被覆寫」的方法/屬性/索引子/事件。
C# abstract 可修飾:class、method、property、indexer、event。這符合「面向介面程式設計」的核心——定義類別的門面契約。23 種設計模式多建構於抽象之上,abstract 正是生逢其時的關鍵字。
virtual 為關鍵字,abstract 為通稱;C# 兩者皆為關鍵字。virtual base class 解決鑽石問題;C# 無多重繼承(單一類別繼承+多介面實作),故無此機制。interface 承擔「契約定義」職責,abstract class 專注「部分實作共享」;C++ 混合在抽象類別中。sealed 禁止繼承/覆寫;C++ 無直接對應(可用私有建構函數或 final(C++11))。interface 定義契約,需共享實作時才引入 abstract class。從 C++ 的 virtual 一統江湖,到 C# 的 interface/abstract/virtual 三權分立,反映了語言設計從「機制導向」向「契約導向」的演進。理解這層脈絡,能讓你在兩語言間自如切換,也能更深刻體會現代物件導向設計的精髓。