Bộ xử lý bắt mọi ngoại lệ
Thuộc phần Logic và luồng chương trình trong hành trình C++ của Coddy. Bài học 52 trên 56.
Đôi khi chương trình có thể gặp lỗi bất ngờ không thuộc các kiểu ngoại lệ cụ thể mà bạn đã dự liệu. Trình xử lý tổng quát catch(...) tạo một lớp bảo vệ, bắt mọi ngoại lệ mà các khối catch cụ thể hơn chưa xử lý.
Bộ xử lý bắt mọi ngoại lệ dùng ba dấu chấm (...) thay vì chỉ định một kiểu ngoại lệ cụ thể. Bạn phải đặt nó sau tất cả các khối catch khác vì C++ kiểm tra chúng theo thứ tự:
try {
// Đoạn code có thể phát sinh nhiều loại ngoại lệ (exception)
} catch (std::invalid_argument& e) {
std::cout << "Invalid input!" << std::endl;
} catch (std::out_of_range& e) {
std::cout << "Number too large!" << std::endl;
} catch (...) {
std::cout << "An unexpected error occurred!" << std::endl;
}Trình xử lý tổng quát đóng vai trò dự phòng cho mọi loại ngoại lệ mà các khối lệnh trước đó chưa bắt. Cách này đặc biệt hữu ích khi bạn làm việc với code có thể phát sinh những ngoại lệ bạn không lường trước, giúp chương trình không bị sập do lỗi bất ngờ.
Dù không thể truy cập thông tin cụ thể về ngoại lệ trong khối bắt tất cả, bạn vẫn có thể đưa ra thông báo lỗi chung và thực hiện các thao tác dọn dẹp để chương trình tiếp tục chạy ổn định.
Thử thách
DễTạo một chương trình minh họa cách xử lý ngoại lệ toàn diện bằng nhiều khối catch, bao gồm cả trình xử lý bắt tất cả. Thử thách này sẽ kiểm tra mức độ hiểu biết của bạn về cách xử lý cả những kiểu ngoại lệ cụ thể lẫn các lỗi bất ngờ không thuộc các danh mục đã định trước.
Chương trình sẽ nhận các đầu vào sau:
- Một chuỗi
testTypebiểu thị kiểu kiểm tra cần thực hiện ("string_convert","math_operation","array_access"hoặc"unknown_error") - Một chuỗi
value1dùng làm dữ liệu chính cho phép toán - Một chuỗi
value2dùng làm dữ liệu phụ cho một số phép toán
Chương trình của bạn cần:
- Tạo một hàm có tên
performTestnhận ba tham số kiểu chuỗi - Bên trong hàm, dùng cấu trúc if-else để xử lý các kiểu kiểm tra khác nhau:
- Nếu testType là
"string_convert": dùngstd::stoiđể chuyển value1 thành số nguyên rồi in ra - Nếu testType là
"math_operation": dùngstd::stoiđể chuyển cả value1 và value2 thành số nguyên, sau đó chia value1 cho value2 rồi in kết quả - Nếu testType là
"array_access": tạo một chuỗi"Programming", dùngstd::stoiđể chuyển value1 thành chỉ số nguyên, sau đó dùngstr.at(index)để truy cập ký tự tại chỉ số đó và in ra. Phương thức.at()tự động némstd::out_of_rangenếu chỉ số không hợp lệ: không cần kiểm tra giới hạn thủ công - Nếu testType là
"unknown_error": ném một giá trị số nguyên999 - Trong hàm main, gọi
performTestbên trong khốitry - Dùng nhiều khối
catchđể xử lý ngoại lệ theo đúng thứ tự sau: - Thứ nhất:
std::invalid_argument&cho trường hợp chuyển chuỗi thành số không hợp lệ - Thứ hai:
std::out_of_range&cho số quá lớn hoặc chỉ số chuỗi vượt giới hạn - Thứ ba:
catch(...)làm trình xử lý bắt tất cả các kiểu ngoại lệ khác
Dùng định dạng đầu ra chính xác sau:
Với các phép toán thành công:
Success: [result_value]Với các kiểu ngoại lệ khác nhau:
Invalid argument caught
Out of range caught
Unknown exception caughtHãy nhớ đặt trình xử lý bắt tất cả catch(...) ở cuối vì C++ kiểm tra các khối catch theo thứ tự. Trình xử lý này sẽ bắt mọi kiểu ngoại lệ chưa được xử lý bởi các khối catch cụ thể đứng trước, bao gồm cả ngoại lệ số nguyên được ném trong trường hợp "unknown_error". Trình xử lý bắt tất cả tạo một lớp bảo vệ trước các lỗi bất ngờ, đồng thời vẫn cho phép xử lý cụ thể những kiểu ngoại lệ đã biết.
Tự làm thử
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
// TODO: Viết code ở đây để tạo hàm (function) performTest
int main() {
// Đọc đầu vào
string testType;
string value1;
string value2;
cin >> testType;
cin >> value1;
cin >> value2;
// TODO: Viết code bên dưới để triển khai các khối lệnh try-catch và gọi performTest
return 0;
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng chương trình
1Con trỏ và bộ nhớ
Con trỏ là gì?Toán tử lấy địa chỉToán tử giải tham chiếuCon trỏ nullCon trỏ và mảngBộ nhớ động với newGiải phóng bộ nhớ với deleteÔn tập: luyện tập về con trỏ2Vector (mảng động)
Giới thiệu std::vectorTạo vectorThêm phần tửTruy cập phần tửKích thước vectorDuyệt bằng vòng lặp forVòng lặp for dựa trên phạm viXóa phần tửÔn tập: các thao tác với vector5Dự án: Công cụ quản lý hàng tồn kho
Thiết lập dự ánThêm và cập nhật mặt hàng8Xử lý lỗi cơ bản
Giới thiệu về ngoại lệKhối lệnh 'try' và 'catch'Từ khóa 'throw'Các kiểu ngoại lệ khác nhauBộ xử lý bắt mọi ngoại lệÔn tập: phép chia an toàn3Dự án: Công cụ danh sách công việc
Tổng quan dự ánThêm công việc6Tập hợp (các phần tử duy nhất)
Giới thiệu std::setTạo tập hợp và thêm phần tửKiểm tra phần tửXóa phần tửDuyệt qua tập hợpÔn tập: các số duy nhấtTự luyện tập: Trình biên dịch C++ online