「物件自殺」指:物件**主動決定**結束自身生命週期,而非被擁有者 delete。本文剖析四類典型自殺場景,對比四種實現策略(發送訊息、回調、開線程自刪、垃圾回收站),並強調「自殺」與「借刀殺人」的本質區別。
delete以上皆為**被動**銷毀,控制權在外部。
視頻播放器物件:上層建立並傳入資源資訊 → 物件內部執行播放 → **只有物件知道何時播完** → 上層無法及時感知 → 物件自殺最乾淨,或通知上層「可殺我」。
網路發送器:上層塞數據到緩衝區 → 物件定時發送 → 上層發現數據全塞完 → 通知物件「可自殺」 → 物件**等緩衝區排空後**才自殺。
發送器遇網路嚴重錯誤 → 繼續發送會污染接收端 → 物件決定**立即停止並自殺**,確保資源釋放與後續邏輯正常。
以上場景均可用「上層輪詢狀態」替代,自殺只是**另一條路徑**。核心區別:控制權在物件內部。
delete this)delete(如發送訊息、回調)| 策略 | 分類 | 適用環境 | 關鍵風險 | 缓解措施 |
|---|---|---|---|---|
| 1. 發送訊息 (PostMessage/SendMessage) | 借刀 | MFC 架構 | 訊息循環未運行時失效 | 確保訊息泵正常 |
| 2. 回調函數 | 借刀 | 非 MFC、跨模組 | 回調中 delete 後調用棧返回訪問已死對象 | 回調最後執行 delete,或標記「已死」防重入 |
| 3. 開線程 delete this | 自行了斷 | 通用 C++ | 外部不知物件已死,持有懸空指標 | 自殺前/後通知外部置空指標,或用 weak_ptr |
| 4. 垃圾回收站 (專用線程掃描回收) | 自行了斷 | 大量短命物件 | 同策略 3,延遲回收窗口更大 | 同策略 3,回收站提供「已回收」查詢介面 |
class Task {
public:
void RequestSuicide() {
std::thread([this]() {
// 可選:通知外部「我要死了」
delete this; // 線程上下文中安全刪除
}).detach();
}
// 成員函數不可在 delete this 後繼續執行任何代碼!
};
delete this **之後絕不可執行任何成員代碼**(含返回語句),this 已失效std::weak_ptr 觀察std::atomic 標記狀態)物件自殺是「控制權內移」的設計選擇。理解四大場景、兩種本質、四種策略及風險,能在必要時做出正確決策。現代 C++ 應優先用 RAII/智慧指標表達生命週期。本文出自「對影成三人」博客。