C++ 物件解構時機取決於建立方式與作用域。搞懂這兩點,才能避免記憶體洩漏與未定義行為。
class A { public: ~A() { cout << "解構 A" << endl; } };
void main() {
A a; // 常規建立(堆疊)
A* p = new A; // 動態建立(堆積)
}
| 建立方式 | 解構時機 | 關鍵規則 |
|---|---|---|
| 常規 (堆疊) | 離開變數作用域時自動呼叫 | 如同區域變數,作用域結束即解構 |
| 動態 (堆積) | 呼叫 delete 指標 時 | 指標離開作用域不會自動解構物件 → 記憶體洩漏 |
class A { ~A() { cout << "解構A" << endl; } };
class B { ~B() { cout << "解構B" << endl; } };
void main() {
A* p = NULL;
{ // 內層作用域開始
p = new A; // 動態建立 A
B b; // 常規建立 B
} // 內層作用域結束
} // 外層作用域結束(程式結束)
輸出:
解構B
分析:
b 為常規物件,隨內層作用域結束自動解構 → 印出「解構B」p 指向動態物件,作用域屬於指標 p(外層),內層結束不影響 → 物件存活,若程式結束前未 delete p 即洩漏
void main() {
A* p = NULL;
{
A a; // 堆疊物件
p = &a; // 指標指向它
} // a 解構,p 變成懸空指標
}
此時 a 隨作用域解構,p 雖在外層仍存活,但指向已銷毀記憶體 → 未定義行為。
delete常規物件:看物件本身作用域。
動態物件:看delete 指標動作。
指標離開作用域 ≠ 物件解構。