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

C++ 虛函數深度解析:多態實現機制、虛析構與純虛函數

     編輯:關於C++

虛函數的核心作用

虛函數實現動態多態:基類指針/引用指向派生類對象時,調用虛函數會根據對象真實類型在運行期綁定到正確的函數實現,而非編譯期靜態綁定。

虛函數表與指針

  • 編譯期為每個含虛函數的類建立虛函數表,存放虛函數地址。
  • 每個對象內部隱含一個 vptr 指向其類的虛表。
  • 調用虛函數時:obj->vptr[index](),實現動態分派。

非虛函數的靜態綁定問題

class Student { public: void display() { /* ... */ } };
class Graduate : public Student { public: void display() { /* ... */ } };

Student* p = new Graduate;
p->display(); // 輸出 Student::display,因為非虛函數靜態綁定

加上 virtual 後,同樣代碼輸出 Graduate::display。

何時應聲明虛函數?

  1. 類作為基類,且派生類可能改變行為。
  2. 需透過基類指針/引用調用該函數。
  3. 函數在基類無具體實現,僅定義介面(純虛函數)。

虛析構函數:必須虛擬的析構函數

基類指針 delete 派生類對象時,若析構函數非虛,僅調用基類析構函數,派生類部分資源洩漏。

class Base { public: virtual ~Base() {} }; // 必須 virtual
class Derived : public Base { /* ... */ };

Base* p = new Derived;
delete p; // 正確調用 Derived::~Derived() -> Base::~Base()

規則:基類析構函數一旦聲明 virtual,所有派生類析構函數自動成為虛函數。

純虛函數與抽象類

class Shape {
public:
    virtual void draw() = 0; // 純虛函數
    virtual ~Shape() {}
};
  • 含純虛函數的類為抽象類,不可實例化。
  • 派生類必須實現所有純虛函數,否則仍為抽象類。
  • 純虛函數可有函數體(罕見),供派生類調用 Base::func()。

虛函數的限制

  • 構造函數不能是虛函數:構造期間對象類型尚未確定,vptr 未初始化完成。
  • 內聯函數通常不會被虛調用內聯:編譯器無法在編譯期確定具體調用目標。
  • 靜態成員函數不能是虛函數:無 this 指針,無法關聯對象。
  • 友元函數不能是虛函數:非類成員,無法納入虛表。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved