Từ khóa throw dùng để ném một ngoại lệ (exception) khi phát hiện điều kiện lỗi. Ngoại lệ có thể là bất kỳ kiểu dữ liệu nào.
Cú pháp cơ bản
throw expression;
Ví dụ cơ bản: Chia cho 0
#include <iostream>
using namespace std;
double divide(int a, int b) {
if (b == 0) {
throw "Lỗi: Chia cho 0!"; // ném const char*
}
return static_cast(a) / b;
}
int main() {
int x = 50, y = 0;
try {
double result = divide(x, y);
cout << "Kết quả: " << result << endl;
} catch (const char* msg) {
cerr << "Ngoại lệ: " << msg << endl;
}
return 0;
}
Kết quả
Ngoại lệ: Lỗi: Chia cho 0!
Các kiểu dữ liệu thường ném
1. Chuỗi literal (C-style)
throw "Error message";
Đơn giản nhưng không khuyến khích (không có thông tin kiểu, stack trace).
2. std::exception và lớp dẫn xuất (Khuyến nghị)
#include <stdexcept>
#include <string>
throw std::runtime_error("File not found: " + filename);
throw std::invalid_argument("Invalid parameter: " + paramName);
throw std::out_of_range("Index " + to_string(i) + " out of range");
throw std::logic_error("Logic error");
throw std::bad_alloc(); // hết bộ nhớ
3. Custom exception class
class MyException : public std::exception {
string message;
public:
MyException(const string& msg) : message(msg) {}
const char* what() const noexcept override { return message.c_str(); }
};
// Sử dụng
throw MyException("Custom error details");
4. Ném đối tượng kiểu tự định nghĩa
struct ErrorInfo {
int code;
string message;
string file;
int line;
};
throw ErrorInfo{404, "Not found", __FILE__, __LINE__};
Quy tắc tốt (Best Practices)
- Ném bằng giá trị, bắt bằng const reference:
catch (const MyException& e) - Kế thừa từ
std::exceptionđể tương thích chuẩn - Ghi đè
what()trả về mô tả lỗi - Không ném trong destructor (gọi
std::terminate) - Dùng
noexceptcho hàm không ném ngoại lệ
Re-throw (ném lại)
catch (const std::exception& e) {
log(e.what());
throw; // ném lại nguyên vẹn exception hiện tại
}