Trong C++, Xử lý ngoại lệ (Exception Handling) là quá trình xử lý các lỗi runtime. Ngoại lệ (Exception) là một sự kiện được ném (thrown) tại runtime trong C++. Tất cả các ngoại lệ đều kế thừa từ lớp std::exception. Đây là lỗi runtime có thể được xử lý. Nó in thông báo ngoại lệ và chấm dứt chương trình nếu chúng ta không xử lý ngoại lệ.
Các ngoại lệ được định nghĩa trong chuẩn C++ như lớp

Các lớp ngoại lệ phổ biến trong C++:
| STT | Ngoại lệ & Mô tả |
|---|---|
| 1 | std::exception Là ngoại lệ cơ sở và lớp cha của tất cả các ngoại lệ chuẩn C++. |
| 2 | std::bad_cast Ngoại lệ được ném bởi dynamic_cast. |
| 3 | std::bad_exception Xử lý các ngoại lệ bất ngờ trong chương trình C++. |
| 4 | std::bad_alloc Thường được ném bởi toán tử new khi cấp phát bộ nhớ thất bại. |
| 5 | std::logic_failure (thường là std::logic_error) Ngoại lệ có thể phát hiện bằng cách đọc code (logic sai). |
| 6 | std::runtime_error Ngoại lệ không thể phát hiện bằng cách đọc code (lỗi runtime). |
| 7 | std::bad_typeid Ngoại lệ được ném bởi typeid. |
Từ khóa
Có 3 từ khóa trong xử lý ngoại lệ: try, catch và throw.
Khối Try/Catch
Trong C++, xử lý ngoại lệ được thực hiện bằng câu lệnh try/catch. Code có thể gây ngoại lệ được đặt trong khối try. Khối catch được dùng để xử lý ngoại lệ.
Mã ví dụ
#include <iostream>
using namespace std;
class Sample1 {
public:
Sample1() {
cout << "Construct an Object of sample1" << endl;
}
~Sample1() {
cout << "Destruct an Object of sample1" << endl;
}
};
class Sample2 {
public:
Sample2() {
int i = 7;
cout << "Construct an Object of sample2" << endl;
throw i;
}
~Sample2() {
cout << "Destruct an Object of sample2" << endl;
}
};
int main() {
try {
Sample1 s1;
Sample2 s2;
} catch(int i) {
cout << "Caught " << i << endl;
}
return 0;
}
Kết quả đầu ra
Construct an Object of sample1 Construct an Object of sample2 Destruct an Object of sample1 Caught 7
Lưu ý: Destructor của Sample2 không được gọi vì ngoại lệ xảy ra trong constructor.
Ngoại lệ tự định nghĩa (User Defined Exception)
Chúng ta có thể định nghĩa ngoại lệ riêng bằng cách kế thừa và ghi đè chức năng của lớp exception.
Mã ví dụ
#include <iostream>
#include <exception>
using namespace std;
struct DivideByZero : public exception {
const char * what() const throw() {
return "My Exception";
}
};
int main() {
try {
throw DivideByZero();
} catch(DivideByZero& e) {
cout << "Exception caught" << endl;
cout << e.what() << endl;
} catch(exception& e) {
}
return 0;
}
Kết quả đầu ra
Exception caught My Exception
what() = phương thức public do lớp exception cung cấp và đã được ghi đè bởi tất cả các lớp ngoại lệ con. Nó trả về nguyên nhân của ngoại lệ.