| 模型 | 特點 | 缺點 |
|---|---|---|
| 簡單對象模型 | 對象存指針表,成員統一間接訪問 | 空間浪費、訪問慢、對象大小隨成員數變化 |
| 表格驅動模型 | 數據表 + 函數表,對象存兩表指針 | 雙重間接、空間固定但訪問開銷大 |
| C++ 實際模型 | 非靜態數據成員內嵌對象,其餘外置;虛函數表 + vptr 支援多態 | 非靜態數據成員變更需重編譯 |

type_info 指針,支援 dynamic_cast/typeidclass Base {
public:
Base(int v) : iBase(v) {}
virtual ~Base() {}
virtual void print() const { cout << "Base::print" << endl; }
int getIBase() const { return iBase; }
static int instanceCount() { return count; }
protected:
int iBase;
static int count;
};
// 測試函數通過地址運算解析 vptr、虛表項、數據成員位置
// 輸出驗證: 對象首地址 = vptr; vptr[0] = 析構函數; vptr[1] = print(); 數據成員緊隨 vptr 後
[vptr][Base::iBase][Derived::iDerived][vptr_Base1][Base1數據][vptr_Base2][Base2數據][Derived數據]0x0 分隔[vptr_Derived][Derived數據][0x0][vptr_Base][Base數據]0x0 分隔Base* p = new Derived();
p->print_virtual(); // 動態綁定: p->vptr -> Derived虛表 -> Derived::print_virtual()
p->print(); // 靜態綁定: Base::print() (非虛函數)
**必要條件**:① 虛函數 ② 基類指針/引用指向派生對象 ③ 派生類重寫 (override)
Base* p = new Derived();
delete p; // 若 ~Base() 非虛: 僅調用 ~Base() → 內存洩漏!
// 若 ~Base() 虛: 調用 ~Derived() -> ~Base() 正確釋放
模型視角:非虛析構不在虛表中,派生類無法 override,刪除基類指針時無法分發到派生類析構函數。
class Base { virtual void f(); }; // sizeof = 4/8 (vptr)
class Derived : public Base {}; // sizeof = 4/8 (共用 vptr)
class VDerived : virtual public Base {}; // sizeof = 12/24 (vptr + vbptr + padding)