Khi một exception được ném ra nhưng không có khối catch phù hợp nào, chương trình sẽ gọi std::terminate() để kết thúc. C++ cho phép tùy chỉnh hàm xử lý này thông qua std::set_terminate.
Ví dụ cơ bản
#include <exception>
#include <iostream>
using namespace std;
// Custom terminate handler
void my_terminate_handler() {
cout << "Trong custom terminate handler\n";
abort(); // Buộc kết thúc chương trình
}
int main() {
// Đăng ký handler tùy chỉnh
set_terminate(my_terminate_handler);
try {
cout << "Trong try block\n";
throw 100; // Ném int, nhưng catch chỉ bắt char
}
catch (char c) {
cout << "Trong catch block\n";
}
// Không có catch(int) → terminate() được gọi → my_terminate_handler chạy
return 0;
}
Đầu ra
Trong try block Trong custom terminate handler
Các hàm liên quan
| Hàm | Chức năng |
|---|---|
std::set_terminate(handler) | Đặt handler mới, trả về handler cũ |
std::get_terminate() | Lấy handler hiện tại (C++11) |
std::terminate() | Gọi handler hiện tại (mặc định gọi abort()) |
std::set_unexpected(handler) | Deprecated C++11, removed C++17 (dành cho dynamic exception spec) |
Yêu cầu đối với terminate handler
- Không được trả về (phải gọi
abort(),exit(),_Exit(), hoặc ném exception khác). - Nếu handler trả về → hành vi không xác định.
- Handler không được ném exception (trừ khi nó tự xử lý).
Ví dụ thực tế: Ghi log trước khi crash
#include <exception>
#include <iostream>
#include <fstream>
#include <ctime>
void crash_logger() {
ofstream log("crash.log", ios::app);
time_t now = time(nullptr);
log << "CRASH at " << ctime(&now);
log << "Unhandled exception - terminating\n";
log.close();
abort();
}
int main() {
set_terminate(crash_logger);
// ... code có thể ném exception không bắt được
}
Lưu ý
Trong C++11 trở đi, std::terminate cũng được gọi khi:
- Destructor ném exception trong lúc stack unwinding.
noexceptfunction ném exception.- Không đủ bộ nhớ cho exception object.