C++ 為支援多型引入虛函數表 (vtable),為解決多重繼承的資料重複與二義性引入虛繼承。這使類別記憶體佈局呈現層次複雜性。本文由淺入深剖析三種情況。
class Top { int topVar; };
class LBase : public Top { int lVar; };
class RBase { int rVar; };
class Derived : public LBase, public RBase { int var1, var2; };
Derived 物件: +----------------+ | Top::topVar | <- LBase 繼承自 Top | LBase::lVar | +----------------+ | RBase::rVar | <- 第二個基底 +----------------+ | Derived::var1 | | Derived::var2 | +----------------+

class Top {
virtual void vTop() = 0;
int topVar;
};
class LBase : public Top {
virtual void vL() {}
void vTop() override {} // 實作純虛函數
int lVar;
};
class RBase {
virtual void vR() {}
int rVar;
};
class Derived : public LBase, public RBase {
void vL() override {} // 覆寫
int var1, var2;
};
Derived 物件: +----------------+ <- LBase 子物件 (第一個基底) | vptr → LBase vtable | (含 Top::vTop, LBase::vL, Derived::vL) | Top::topVar | | LBase::lVar | +----------------+ | vptr → RBase vtable | <- RBase 子物件 (第二個基底) | RBase::rVar | +----------------+ | Derived::var1 | | Derived::var2 | +----------------+

class B { int b; };
class X : public B { int x; };
class Y : public B { int y; };
class Z : public X, public Y { int z; }; // Z 含兩份 B::b → 二義性
virtual public B:基底 B 在最衍生類別中只有一份 (共享)。class B { virtual void f() = 0; int b; };
class X : virtual public B { int x; void f() override {} };
class Y : virtual public B { int y; };
class Z : public X, public Y { int z; void f() override {} }; // 僅一份 B
Z 物件: +----------------+ | vptr → X vtable | (含 B::f, X::f, Z::f) | X::x | +----------------+ | vptr → Y vtable | | Y::y | +----------------+ | Z::z | +----------------+ | B::b | <- 共享虛基底,放在最後 +----------------+

| 場景 | vptr 數量 | 基底子物件份數 | 虛基底位置 |
|---|---|---|---|
| 單一繼承 + 虛函數 | 1 | 1 | N/A |
| 多重繼承 + 虛函數 | 每個有虛函數的基底一個 | 每個基底一份 | N/A |
| 虛繼承 | 每個虛基底路徑一個 | 虛基底共享 1 份 | 通常在最衍生類別成員後 |
dynamic_cast、static_cast 跨基底轉型時,虛繼承影響指標調整邏輯。