| 階段 | 順序 | 口訣 |
|---|---|---|
| 構造 | 基類 → 派生類 | 地基先蓋,樓層後蓋 |
| 析構 | 派生類 → 基類 | 樓層先拆,地基後拆 |
#include <iostream>
using namespace std;
class A { public: A() { cout << "A constructor" << endl; } ~A() { cout << "A destructor" << endl; } };
class B : public A { public: B() { cout << "B constructor" << endl; } ~B() { cout << "B destructor" << endl; } };
class C : public B { public: C() { cout << "C constructor" << endl; } ~C() { cout << "C destructor" << endl; } };
int main() { C test; } // 區域物件,作用域結束自動析構
A constructor B constructor C constructor C destructor B destructor A destructor
完美印證:構造 A→B→C,析構 C→B→A。
遵循基類聲明順序逆序:
class D : public BaseA, public BaseB { ... };
// 析構順序:
// 1. Derived
// 2. BaseB (聲明第二)
// 3. BaseA (聲明第一)
class Base {
public:
virtual ~Base() { cout << "Base destructor" << endl; } // 必須 virtual
};
class Derived : public Base {
public:
~Derived() { cout << "Derived destructor" << endl; }
};
int main() {
Base* p = new Derived();
delete p; // 正確調用 Derived → Base
}
無 virtual 時,delete p 僅調用 Base::~Base(),導致 Derived 資源洩漏。
析構函數是 RAII (Resource Acquisition Is Initialization) 的執行點:
delete/delete[]/智慧指標)=default)virtual(隱式虛函數),但建議加 override(C++11)noexcept 隱式)unique_ptr, vector, lock_guard)自動管理,減少手寫析構| 錯誤 | 後果 | 修正 |
|---|---|---|
| 基類析構非 virtual | 多態 delete 洩漏派生資源 | 加 virtual |
| 派生類析構未釋放自身資源 | 資源洩漏 | 完整實現清理邏輯 |
| 析構中調用虛函數 | 行為未定義 (vptr 已失效) | 避免,或用 NVI 模式 |
| 析構拋出異常 | 程式終止 (雙重異常) | 捕獲內部處理,不外拋 |
析構函數是 C++ 確定性資源管理的基石。自動逆序調用機制確保子物件先於父物件銷毀,虛析構確保多態刪除正確釋放完整物件。掌握構造/析構鏡像順序、虛析構必要性、RAII 核心地位,是編寫無洩漏、異常安全 C++ 代碼的核心功力。