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

C++ Primer Plus 學習筆記:虛函數與動態多態實現機制

     編輯:C++ 入門

多態性分類

  • 靜態多態:函數重載、運算符重載、模板——編譯期確定
  • 動態多態:虛函數——運行期根據對象實際類型確定調用

虛函數核心概念

  • 基類指針/引用指向派生類對象,調用虛函數時根據對象實際類型執行對應版本
  • 基類中用 `virtual` 聲明,派生類重寫時函數簽名必須完全一致(返回類型、函數名、參數列表、const 屬性)
  • 構造函數不能是虛函數,析構函數通常聲明為虛函數

動態綁定底層機制:VTABLE 與 VPTR

  1. 編譯器為每個含虛函數的類創建虛函數表,存儲該類虛函數地址
  2. 每個對象隱含一個虛指針,指向其類的 VTABLE
  3. 基類指針調用虛函數時:取對象 VPTR → 查 VTABLE 找函數地址 → 調用
  4. 此過程在運行期完成,故稱「晚期綁定」或「動態綁定」

虛函數重寫規則(關鍵)

派生類重寫虛函數不是普通重載,必須滿足:

  • 函數名相同
  • 返回類型相同(或協變返回類型)
  • 參數個數、類型、順序完全相同
  • const/volatile 屬性一致
  • 否則會導致虛特性丟失,變為隱藏而非覆蓋

經典示例:圖形面積計算

#include <iostream>
using namespace std;

class Figure {
public:
    void set(double a=0, double b=0) { x=a; y=b; }
    virtual void show_area() { 
        cout << "No area computation defined\n"; 
    }
protected:
    double x, y;
};

class Triangle : public Figure {
public:
    void show_area() override {
        cout << "Triangle: " << 0.5*x*y << '\n';
    }
};

class Rectangle : public Figure {
public:
    void show_area() override {
        cout << "Rectangle: " << x*y << '\n';
    }
};

class Circle : public Figure {
public:
    void show_area() override {
        cout << "Circle: " << 3.14*x*x << '\n';
    }
};

int main() {
    Figure* f;
    Triangle t; Rectangle r; Circle c;
    
    f = &t; f->set(10,5); f->show_area(); // 25
    f = &r; f->set(10,5); f->show_area(); // 50
    f = &c; f->set(10);   f->show_area(); // 314
}

關鍵點總結

  1. 基類指針/引用是實現動態多態的前提
  2. VTABLE/VPTR是編譯器實現動態綁定的核心數據結構
  3. override關鍵字(C++11)可防止簽名不匹配導致的隱藏錯誤
  4. 析構函數虛化:刪除基類指針指向派生對象時,保證正確調用派生類析構函數
  5. 純虛函數(`=0`)定義抽象類,強制派生類實現接口

虛函數是 C++ 面向對象多態的基石,理解其底層機制有助於編寫高效、正確的多態代碼。

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