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

C++ 純虛類(抽象類)深度解析:定義、特性、虛表機制與實戰陷阱

     編輯:關於C++

定義與引入動機

  • 純虛函數:virtual ReturnType Func() = 0;,基類不提供實現,強制派生類覆寫。
  • 純虛類(抽象類):含 ≥1 純虛函數的類。不能實例化(無對象),僅作為接口/基類使用。
  • 動機:1) 方便多態;2) 基類本身不應生成對象(如「動物」類)。

核心特性

  1. 不可實例化;派生類若未覆寫所有純虛函數,亦為抽象類。
  2. 可擁有:成員變量、普通成員函數、非純虛函數、構造函數(含帶參構造)、protected 構造函數(防止直接構造基類)。
  3. 派生類構造函數可顯式調用基類帶參構造。
  4. 可定義指向抽象類的指針/引用,實現多態(指向派生類對象)。
  5. 設計意圖:位於繼承層次上層,提供公共操作接口語義,完整實現留給派生類。

純虛類與虛函數表

虛表存在嗎?

存在。雖然抽象類無對象,但編譯器仍為其生成虛表(含純虛函數條目),用於:

  • 派生類覆寫時,確保虛函數在虛表中偏移量固定、正確。
  • 基類構造函數中調用虛函數時(見下文陷阱),虛表指針已初始化指向基類虛表。

構造函數中調用純虛函數:運行時錯誤

class Base {
    Base() { nonVirtual(); } // 構造時調用
    void nonVirtual() { pureVirtual(); } // 間接調用純虛
    virtual void pureVirtual() = 0;
};
class Derived : public Base {
    void pureVirtual() override {} // 實現
};
int main() { Derived d; } // Crash: pure virtual function called

原因:構造 Derived 時,先構造 Base 子對象,此時 vptr 指向 Base 虛表(純虛條目通常填入 __cxa_pure_virtual),調用純虛觸發運行時錯誤。規則:構造/析構函數中不要調用虛函數。

純虛類作為接口的最佳實踐

class Animal {
protected: Animal() {} // 防止直接構造
public:
    virtual void eat(const string& food) = 0;
    virtual ~Animal() {} // 虛析構函數!
};
class Dog : public Animal {
    vector foodList;
    void eat(const string& f) override {
        if (binary_search(foodList.begin(), foodList.end(), f)) cout << "Yummy\n";
    }
};

總結

純虛類是 C++ 實現「接口」的核心機制。關鍵點:不可實例化、強制派生類實現、虛表仍存在、構造/析構中禁調虛函數、虛析構函數必備。正確使用能構建清晰、可擴展的多態體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved