Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Cách hoạt động của ngoại lệ (Exception) trong C++

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 mà chúng ta có thể sử dụng trong chương trình. Sơ đồ phân cấp lớp cha-con được hiển thị bên dưới:

Cách hoạt động của ngoại lệ (Exception) trong C++

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ệ.