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

C++ 虛函數與抽象類完整教學:從多型機制到純虛函數設計模式

     編輯:關於C++

前言

虛函數是 C++ 實現執行期多型的核心,抽象類則定義了介面契約。本文系統講解虛函數作用、使用方法、限制、虛解構子必要性、純虛函數語意與抽象類設計模式,附完整程式碼驗證。

一、虛函數:突破靜態繫結

1.1 問題:靜態繫結的侷限


class Time { public: void show() { cout << "Time"; } };
class LocalTime : public Time { public: void show() { cout << "LocalTime"; } };

Time* pt = new LocalTime;
pt->show();  // 輸出 "Time" - 靜態繫結到 Time::show()

基類指標指向衍生物件,呼叫非虛函數時依指標型別而非物件型別決定。

1.2 解決:虛函數實現動態繫結


class Time { public: virtual void show() { cout << "Time"; } };
// LocalTime 不變
Time* pt = new LocalTime;
pt->show();  // 輸出 "LocalTime" - 動態繫結

編譯器在衍生類別物件中放置虛函數表指標 (vptr),指向該類別的虛函數表 (vtable),執行時查表繫結。

1.3 虛函數使用規範

  1. 基類用 virtual 宣告
  2. 衍生類別覆寫:同名、同參數、同回傳型別 (或共變返回)
  3. 未覆寫則繼承基類版本
  4. 共變返回型別:基類回傳 Base*,衍生類別可回傳 Derived*

二、虛函數限制

限制說明
僅限成員函數非成員函數不可為虛函數
不可為 static靜態成員無 this 指標,屬於類別非物件
不可為 inline內聯需編譯期確定位址,虛函數需執行期查表
建構子不可虛建構時 vptr 尚未初始化,物件型別確定
空間開銷每類別一 vtable,每物件一 vptr (通常 4/8 bytes)

三、虛解構子:正確釋放衍生資源

問題示範


class Time { public: ~Time() { cout << "Time dtor"; } };
class LocalTime : public Time { public: ~LocalTime() { cout << "LocalTime dtor"; } };

Time* p = new LocalTime;
delete p;  // 僅輸出 "Time dtor" - 衍生解構子未呼叫,資源洩漏

解決:基類解構子宣告 virtual


class Time { public: virtual ~Time() { cout << "Time dtor"; } };
// 輸出:LocalTime dtor -> Time dtor (正確順序)

鐵律:只要類別有虛函數,解構子必須宣告為 virtual。

四、純虛函數與抽象類

4.1 純虛函數語法與語意


class Shape {
public:
    virtual void draw() = 0;  // 純虛函數:無函數體,=0 僅標記
    virtual ~Shape() = default;
};
  • 告訴編譯器:「此處宣告介面,留待衍生類別實作」
  • 可選擇提供定義 (供衍生類別 Base::func() 呼叫)
  • 衍生類別未全部實作純虛函數 → 仍為抽象類別

4.2 抽象類特性

  • 不可實例化物件
  • 可定義指標/參考指向具體衍生物件
  • 作為介面基類,定義「契約」而非「實作」

五、完整程式碼驗證


#include 
#include 
using namespace std;

class Time {
public:
    Time(int h=0,int m=0,int s=0):hour(h),min(m),sec(s) {}
    virtual void show() { cout << hour << ":" << min << ":" << sec << endl; }
    virtual ~Time() { cout << "Time destructor" << endl; }
protected:
    int hour, min, sec;
};

class LocalTime : public Time {
public:
    LocalTime(int h=0,int m=0,int s=0,string z="+8"):Time(h,m,s),zone(z) {}
    void show() override { cout << hour << ":" << min << ":" << sec << "@" << zone << endl; }
    ~LocalTime() { cout << "LocalTime destructor" << endl; }
protected:
    string zone;
};

int main() {
    Time t;
    LocalTime lt;
    Time* pt = &t;
    pt->show();  // 0:0:0
    pt = <
    pt->show();  // 0:0:0@+8  動態繫結
    
    Time* p = new LocalTime;
    delete p;  // LocalTime destructor -> Time destructor
    return 0;
}

六、設計模式應用

  • Template Method:基類定義演算法骨架,虛函數延遲具體步驟到衍生類別
  • Strategy:抽象類定義介面,具體策略類別實作,執行期切換
  • Factory Method:抽象建立者宣告虛擬工廠方法,衍生類別決定具體產品
  • Interface Segregation:純虛函數類別作為細粒度介面,避免胖介面

七、總結

虛函數實現「一個介面,多種實作」;虛解構子保證資源正確釋放;純虛函數定義抽象契約;抽象類承載介面規格。掌握這套機制,是 C++ 物件導向設計進階的關鍵門檻。

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