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

C++ 虛析構函數完全指南:何時使用、為什麼必要以及純虛析構函數的特殊規則

     編輯:關於C

為什麼需要虛析構函數?

在 C++ 多型設計中,當我們透過基類指標刪除派生類物件時,若基類析構函數未宣告為 virtual,將導致資源洩漏。編譯器僅會呼叫基類的析構函數,派生類的析構函數不會被執行,造成派生類持有的資源(記憶體、檔案控制代碼、Socket 等)無法正確釋放。

核心規則:帶有 virtual 函數的類必須有 virtual 析構函數

只要一個類被設計為多型用途的基類(即包含至少一個 virtual 函數),它就必須擁有虛析構函數。這是 C++ 核心準則(C.121)的強制要求。反之,若類不打算作為基類,或不涉及多型行為,則不應將析構函數宣告為 virtual,否則會引入虛表指標(vptr),增加每個物件的記憶體開銷(通常 8 位元組於 64 位元系統)。

經典錯誤示範

class Base { public: Base(); ~Base(); }; // 非虛析構函數
class Derived : public Base { /* ... */ };

Base* p = new Derived;
delete p; // 錯誤:僅呼叫 ~Base(),~Derived() 被略過 → 資源洩漏

正確做法

class Base {
public:
    Base();
    virtual ~Base(); // 加上 virtual
};

純虛析構函數:抽象類的特殊需求

若某類別沒有任何成員函數適合宣告為純虛函數,但又想強制其成為抽象類(不可實例化),可將析構函數宣告為純虛:

class Abstract {
public:
    virtual ~Abstract() = 0; // 純虛析構函數
};
// 必須提供定義(即使是空的),否則連結失敗
Abstract::~Abstract() {}

關鍵點:純虛析構函數必須提供定義。因為派生類析構時會隱式呼叫基類析構函數,若無定義會導致連結錯誤。這是 C++ 唯一「純虛函數仍需定義」的例外。

析構順序保證

C++ 保證析構順序:最深層派生類 → 依序向上呼叫每層基類析構函數。虛析構函數機制確保此順序在透過基類指標刪除時依然生效。

總結檢查清單

  • ✅ 類包含 virtual 函數 → 必須宣告 virtual ~ClassName()
  • ✅ 類不作為基類、無多型需求 → 不要加 virtual(避免 vptr 開銷)
  • ✅ 需要抽象類但無其他純虛函數 → 使用 virtual ~Class() = 0; 並提供定義
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved