多態是面向對象編程的核心,簡述為「一個接口,多種實現」。程序運行時才決定調用哪個函數,實現晚綁定。與之對應的是靜態綁定(編譯期確定地址)。
virtual 聲明虛函數,派生類覆蓋它實現多態行為。vptr 指向該表。| 概念 | 條件 | 多態性 |
|---|---|---|
| 覆蓋 | 同名、同參數、基類有 virtual | ✅ 支持 |
| 重載 | 同名、參數列表不同 | ❌ 編譯期綁定 |
| 隱藏 | 派生類同名函數屏蔽基類同名函數(無論參數) | ❌ 非多態 |
class Animal {
public:
virtual void speak() = 0; // 純虛函數
};
// Animal 成為抽象類,不可實例化,派生類必須實現 speak()
用途:定義接口規範,禁止實例化不完整對象(如「動物」本身不具體)。
class Base { virtual void f(float); void g(float); void h(float); };
class Derived : public Base {
virtual void f(float); // 覆蓋
void g(int); // 隱藏 Base::g(float)
void h(float); // 隱藏 Base::h(float) 而非覆蓋
};
Base* pb = new Derived;
Derived* pd = new Derived;
pb->f(3.14); // Derived::f(float) ✅ 多態
pb->g(3.14); // Base::g(float) ❌ 隱藏,靜態綁定
pd->g(3.14); // Derived::g(int) 隱藏導致參數截斷
規則:派生類同名函數若參數不同,無論 virtual 都會隱藏基類同名函數;參數相同但基類無 virtual 也會隱藏。
virtual,確保派生類資源正確釋放。virtual,避免濫用增加開銷。override (C++11) 明確標註覆蓋意圖,編譯器可捕獲簽名不匹配錯誤。