許多從 C 轉 C++ 的開發者習慣用 exit() 甚至 abort() 粗暴終止程序。隨著項目規模增長、模塊解耦需求上升,這種「一鍵了事」會導致資源洩漏、日誌缺失、無法優雅降級。本文展示如何用 **C++ 異常機制** 系統性替換 exit(),實現分層錯誤處理與資源安全釋放。
// 原代碼
void ReadBytes() {
if (error) { printf("error!\n"); exit(-1); }
return nBytesRead;
}
// 改為
void ReadBytes() {
if (error) throw -1; // 拋出 int 異常
return nBytesRead;
}
在主入口或模塊邊界捕獲:
int main() {
try {
ProcessMail();
} catch (int errCode) {
logError(errCode);
return errCode; // 返回碼代替 exit
}
}
class AppException : public std::exception {
public:
AppException(int code, std::string msg) : m_code(code), m_msg(std::move(msg)) {}
int code() const noexcept { return m_code; }
const char* what() const noexcept override { return m_msg.c_str(); }
private:
int m_code;
std::string m_msg;
};
// 業務代碼
void ReadBytes() {
if (error) throw AppException(ERR_IO, "ReadBytes failed: " + getSystemErrorMsg());
}
void ProcessMail() {
try {
init();
while (!shutdown) {
try {
ReadMail();
} catch (const AppException& e) {
if (e.code() == ERR_TRANSIENT) {
retry(); // 可恢復錯誤:重試
} else {
throw; // 不可恢復:向上拋出
}
}
}
} catch (const AppException& e) {
logFatal(e);
throw; // 繼續拋給主函數決定是否退出
}
}
| 維度 | exit() | C++ 異常 |
|---|---|---|
| 資源清理 | 靠運氣/手動 | RAII 自動棧展開 |
| 錯誤信息 | 僅整數碼 | 豐富對象(堆疊、上下文、建議動作) |
| 控制流 | 硬中斷 | 可捕獲、可恢復、可轉換 |
| 測試友好 | 極差 | 優秀 |
std::terminate);std::exception,便於標準捕獲;std::error_code。將 exit() 替換為結構化異常處理,不僅是語法遷移,更是**錯誤處理哲學的升級**:從「崩潰即正義」轉向「可控、可觀測、可恢復」。