Một số mã cấp cao sẽ quát chỉ bắt std::exception
và in what()
. Bạn muốn ép càng nhiều thông tin càng tốt vào cơ chế chung này, nhưng không mất bất kỳ thông tin nào. Xem xét việc triển khai một số thư viện lưu trữ:
archive::archive(const char* filename)
{
ifstream file(filename)
file.exceptions(ios_base::badbit);
open_archive(file); // throws ios_base::failure, or some other low-level exception.
}
Thông tin có sẵn cho lưu trữ không được ghi lại (ví dụ: tên tệp). Bên cạnh đó bạn muốn phân biệt các ngoại lệ đến từ lớp lưu trữ từ các ngoại lệ khác.
archive::archive(const char* filename)
{
try {
ifstream file(filename)
file.exceptions(ios_base::badbit);
open_archive(file); // throws ios_base::failure, or some other low-level exception.
} catch(const std::exception& e) {
throw archive_exception("Can't open archive", filename, e.what());
}
}
Bây giờ chúng tôi đã thêm thông tin ngữ nghĩa cấp cao hơn mà archive
lớp biết được, nhưng chúng tôi cũng bị mất các thông tin về nguyên nhân gốc của vấn đề (loại e
). nested_exception
có nghĩa là để giải quyết vấn đề này:
archive::archive(const char* filename)
{
try {
ifstream file(filename)
file.exceptions(ios_base::badbit);
open_archive(file); // throws ios_base::failure, or some other low-level exception.
} catch(...) {
throw_with_nested(archive_exception("Can't open archive", filename));
}
}
Tất cả thông tin có sẵn được ghi lại. Bây giờ chúng ta có thể lấy nó một cách tổng quát trong trang bắt:
void print_exception_info(const std::exception& e)
{
cerr << e.what() << "\n";
try {
rethrow_if_nested(e);
} catch(const std::exception& ne) {
print_exception_info(ne);
} catch(...) { }
}
int main() {
try {
run();
} catch(const std::exception& e) {
print_exception_info(e);
}
}
Đầu ra sẽ mô tả hơn trước đây. Nó sẽ mô tả các vấn đề bắt đầu từ cấp cao đến cấp thấp:
Không thể mở kho lưu trữ "my_archive.bin"
Truy cập bị từ chối.
Hoặc có lẽ:
Không thể mở kho lưu trữ "my_archive.bin"
Ghi 'AABB' không tìm thấy.
Các chức năng hoạt động với exception_ptr
được thiết kế để chuyển ngoại lệ giữa các chủ đề hoặc nói chung, lưu trữ ngoại lệ để sử dụng sau này. Làm thế nào họ làm việc phụ thuộc vào việc thực hiện. Mục đích là exception_ptr
sẽ là một con trỏ được chia sẻ với đối tượng ngoại lệ. Tuy nhiên khi con trỏ này được tạo ra, khi ném ngoại lệ hoặc khi cố gắng để có được một exception_ptr
với nó, là tùy thuộc vào việc thực hiện. Việc triển khai vẫn miễn phí để sao chép ngoại lệ khi bạn gọi current_exception()
.
Mô tả tốt (tốt nhất?) Có sẵn trong tiêu chuẩn. Bạn có thể đọc bản thảo [có sẵn công khai mới nhất] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf) miễn phí. – ybungalobill