首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 繼承中虛函數、純虛函數、普通函數三者區別詳解

     編輯:關於C++

三種函數類型對比

類型關鍵字實現繼承語義多態性實例化限制
虛函數virtual基類提供默認實現接口繼承 + 實現繼承(可選覆蓋)運行時動態綁定基類可實例化
純虛函數virtual ... = 0基類不提供實現接口繼承(強制派生類實現)運行時動態綁定基類為抽象類,不可實例化
普通函數無基類提供強制實現實現繼承(不建議覆蓋)編譯時靜態綁定基類可實例化

代碼示例

class Base {
public:
    virtual void pureVirtual() = 0;           // 純虛函數:接口契約
    virtual void virtualFunc() { cout << "Base::virtualFunc\n"; } // 虛函數:默認實現
    void normalFunc() { cout << "Base::normalFunc\n"; }          // 普通函數:強制實現
    virtual ~Base() {}  // 基類析構必須虛!
};

class Derived : public Base {
public:
    void pureVirtual() override { cout << "Derived::pureVirtual\n"; }  // 必須實現
    void virtualFunc() override { cout << "Derived::virtualFunc\n"; }  // 可選覆蓋
    void normalFunc() { cout << "Derived::normalFunc\n"; }             // 隱藏而非覆蓋!
};

關鍵行為差異演示

int main() {
    Base* ptr = new Derived();
    Derived* dptr = new Derived();
    
    ptr->pureVirtual();   // Derived::pureVirtual  ✅ 動態綁定
    ptr->virtualFunc();   // Derived::virtualFunc  ✅ 動態綁定
    ptr->normalFunc();    // Base::normalFunc      ❌ 靜態綁定!
    
    dptr->pureVirtual();   // Derived::pureVirtual
    dptr->virtualFunc();   // Derived::virtualFunc
    dptr->normalFunc();    // Derived::normalFunc  ✅ 編譯時綁定到 Derived
    
    delete ptr; delete dptr;
    return 0;
}

核心原理解析

虛函數表(vtable)機制

  • 含虛函數的類,編譯器生成 vtable(虛函數地址表)
  • 每個對象包含 vptr 指向類的 vtable
  • 調用虛函數時:obj->vptr[vtable_index]() 間接跳轉
  • 純虛函數在 vtable 中佔位,地址為 0 或純虛調用處理器

普通函數無多態

  • 編譯時根據指針/引用的靜態類型確定調用哪個函數
  • Base* ptr = new Derived; ptr->normalFunc() → 調用 Base::normalFunc
  • 派生類同名函數是隱藏,而非覆蓋

設計原則總結

  1. 接口繼承用純虛:定義契約,強制實現(如 Drawable::draw())
  2. 默認行為用虛函數:提供缺省實現,允許選擇性覆蓋(如 Animal::makeSound())
  3. 不變行為用普通函數:工具方法、輔助邏輯,禁止覆蓋(用 final 或私有化)
  4. 基類析構必須虛:確保通過基類指針刪除派生對象時正確調用派生析構

常見錯誤避坑

  • ❌ 普通函數加 virtual 以為能多態 → 那是虛函數
  • ❌ 派生類重寫普通函數期望多態 → 只會隱藏,基類指針仍調用基類版本
  • ❌ 忘記基類析構函數加 virtual → 記憶體洩漏、未定義行為
  • ✅ 用 override (C++11) 明確標記覆蓋意圖,編譯器檢查錯誤
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved