Theo this site, bạn hoàn toàn có thể sử dụng để ném một chuỗi hoặc số nguyên. Tôi thấy điều này khá sạch sẽ và dễ hiểu. Đâu là những nhược điểm đối với throw "description of what happened"
thay vì throw std::runtime_error("description of what happened")
?C++ Ngoại lệ: Tại sao sử dụng hoặc mở rộng std :: exception?
Trả lời
Trang web đó ngu ngốc và dạy thiết kế kém.
Nếu bạn ném int
hoặc char*
, thì bạn sẽ chỉ phải bắt nó bằng cách sử dụng int
hoặc char*
. Bạn có thể đủ điều kiện với const
.
Nếu bạn ném std::runtime_error
, thì bạn có thể bắt bằng cách sử dụng std::runtime_error const &
hoặc lớp cơ sở std::exception const &
.
Vì vậy, điều gì tốt về nó?
Các tốt về nó là nếu bạn ném một ngoại lệ sử dụng một lớp học mà cuối cùng có nguồn gốc từ std::exception
, sau đó bạn có thể viết chỉ ONE catch
khối mà chấp nhận ngoại lệ như std::exception const&
, không phân biệt which derived class được sử dụng để ném ngoại lệ.
Dưới đây là một ví dụ:
void f(A & a)
{
if (!check_arg(a))
{
throw std::invalid_argument("invalid argument");
}
else if (!check_size(a))
{
throw std::length_error("invalid length");
}
//code
if(someCondition)
{
//assume your_own_defined_exception's ultimate base is std::exception
throw your_own_defined_exception("condition unsatisfied");
}
//...
}
Bây giờ là phần thú vị:
try
{
f(a); //it can throw exception of at least 3 types!
}
catch(std::exception const &e) //all types can be caught by just one catch!
{
//handle this case
}
Các tốt là bạn không cần viết bacatch
khối chỉ vì f()
có thể ném ba các loại ngoại lệ khác nhau. Bạn có thể viết nhiều hơn một catch
để xử lý chúng khác nhau nếu điều đó có lợi cho bạn theo một cách nào đó. Nhưng điểm cần lưu ý ở đây là: đó là không phải một yêu cầu!
Tóm lại, bạn có thể tận dụng lợi thế của phân cấp lớp.
Chủ yếu là vì khi bạn làm việc với những người khác, bạn phải đồng ý về những gì cần nắm bắt. Nếu tôi cố bắt một số const std::exception&
và bạn ném const char*
, thì tôi sẽ không bắt được nội dung của bạn và những điều xấu có thể xảy ra.
Nó không thực sự quan trọng loại được ném và bị bắt, miễn là tất cả mọi người dính vào nó. Tôi đoán std::exception
được chọn trên const char*
vì nó cho phép bạn đặt nhiều hơn chỉ một chuỗi vào đối tượng ngoại lệ. Nó chỉ linh hoạt hơn.
Nếu bạn làm cho nó một quy tắc trong mã của bạn để ném ngoại lệ chỉ bắt nguồn từ std :: exception sau đó bắt chúng dễ dàng hơn. Nói cách khác, bạn chỉ có thể có một điều khoản bắt trên std :: exception:
catch (std::exception& e)
{
log_message(e);
throw;
}
Nhưng nếu bạn không tuân theo quy tắc này thì bạn phải viết mệnh đề bắt khi không cần.
có rất ít lợi ích khi bắt và thử lại ở mọi lớp, chỉ sử dụng mệnh đề 'catch' nếu bạn thực sự có điều gì đó cần làm (và trong C++, với RAII, điều này đủ hiếm) hoặc" nuốt "nó. –
Tôi thấy hữu ích khi tạo theo dõi ngăn xếp cho các ngoại lệ không được mong đợi. Nó giúp chẩn đoán một lỗi và theo dõi nơi ngoại lệ orginated từ. – sashang
Tôi đồng ý rằng ngăn xếp là hữu ích, tuy nhiên có hai nhược điểm đối với cách tiếp cận của bạn. Đầu tiên nó cắt mã, nó không còn rõ ràng khi một hành động * cụ thể * được thực hiện trong trường hợp ngoại lệ. Thứ hai, nó là một con heo hiệu suất, bởi vì việc thực hiện ngoại lệ Zero Cost được sử dụng bởi các trình biên dịch phổ biến như gcc hoặc Clang đặt một hình phạt khắc nghiệt trên ném. Có khác, và tôi tìm thấy tốt hơn, lựa chọn thay thế. Nền tảng mã cụ thể để nắm bắt các ngăn xếp tại các điểm ném là một; khác là sử dụng RAII để đăng nhập "ghi chú" được thêm vào ngoại lệ trong khi thư giãn. –
Một điểm bổ sung từ anh câu trả lời khác là thế này -
Nếu bạn ném một int hoặc một chuỗi và bạn muốn bắt một lỗi cụ thể mà bạn không thể. Bạn phải nắm bắt tất cả các ngoại lệ "int" và sau đó so sánh các trường hợp bạn muốn nắm bắt, sau đó so sánh lại bất kỳ trường hợp nào bạn chưa sẵn sàng giải quyết. Nếu bạn kế thừa từ ngoại lệ, bạn có thể bắt ngoại lệ cụ thể mà bạn muốn xử lý và vẫn có lợi thế là bạn có thể bắt std :: exception nếu bạn muốn xử lý tất cả.
- 1. Ngoại lệ C++; int hoặc std :: exception?
- 2. Tại sao std :: locale loc ("en_") ném một ngoại lệ?
- 3. ném mới std :: ngoại lệ vs ném std :: ngoại lệ
- 4. Tại sao ngoại lệ C++ của tôi không bị bắt?
- 5. Tại sao điều này C++ 11 std :: ví dụ regex ném một ngoại lệ regex_error?
- 6. C++ Exceptions và thừa kế từ std :: ngoại lệ
- 7. Trong Chrome, tại sao SVG không ngoại lệ mở rộng nội dung vị trí tương đối?
- 8. Mở rộng các lỗi/ngoại lệ JavaScript
- 9. C++ 11: mở rộng std :: is_pointer thành std :: shared_ptr
- 10. Tại sao ngoại lệ thời gian chạy là ngoại lệ không được kiểm soát?
- 11. tại sao ngoại lệ này FileItemStream $ ItemSkippedException?
- 12. C++: Việc sử dụng thích hợp cho std :: logic_error exception là gì?
- 13. Tại sao ngoại lệ win32 không bị bắt bởi cơ chế xử lý ngoại lệ C#
- 14. Tại sao std :: copy (từ istream đến ostream) làm tăng ios :: failure exception?
- 15. xuất phát từ std :: ngoại lệ
- 16. Ném một ngoại lệ từ std :: call_once
- 17. Tại sao tệp mục tiêu C sử dụng phần mở rộng .m?
- 18. C# Ném ngoại lệ khi sử dụng Assert?
- 19. Spring Webflow - truy cập ngoại lệ bằng cách sử dụng thuộc tính transition.on-exception
- 20. Tại sao mã C++ này biên dịch khi sử dụng clang -std = gnu ++ 11?
- 21. Exception grep nhưng loại trừ cụ thể ngoại lệ
- 22. Ngoại lệ tùy chỉnh trong C++
- 23. Tại sao không thể bắt ngoại lệ bên trong?
- 24. Xử lý ngoại lệ bằng cách sử dụng C# Attribute
- 25. Ngoại lệ tràn ngăn xếp — tại sao?
- 26. C++ nhận cuộc gọi ngăn xếp từ std :: ngoại lệ
- 27. Ngoại lệ trong các trường hợp ngoại lệ trong C++
- 28. Tuyên truyền C++ ngoại lệ cho Cython - python ngoại lệ
- 29. Bật ngoại lệ C++
- 30. Tại sao tạo ngoại lệ tùy chỉnh?
Vì vậy, về cơ bản nó tự nhiên cho phép thừa kế để đơn giản hóa thiết kế xử lý lỗi. Khá thanh lịch. Nếu tôi định nghĩa lớp ngoại lệ của riêng mình và làm theo cách đó, tôi có thể tạo ra kết quả tương tự, đúng không? –
@StevenLu Nếu bạn lấy được lớp ngoại lệ của riêng bạn, thì bạn phát minh lại bánh xe và có khả năng phá vỡ mã phụ thuộc vào việc bắt std :: exception. Trong khi điều này có thể tốt cho các dự án cá nhân của bạn, nó làm cho mã của bạn khó phân phối cho người khác. Cách tiếp cận tiêu chuẩn là có một hệ thống phân cấp ngoại lệ dành riêng cho ứng dụng phân lớp 'std :: exception'. Ví dụ, có tất cả các ngoại lệ của bạn là các lớp con của 'StevenLuException', là một lớp con của' std :: exception'. – sfstewman
@StevenLu: Nếu lớp ngoại lệ của bạn xuất phát từ 'std :: exception', thì có đó là thiết kế thanh lịch. Xem ngoại lệ * thứ ba * được gọi là 'your_own_defined_exception' trong mã ví dụ của tôi. Tôi nói nó đã được bắt nguồn từ 'std :: exception' cuối cùng. – Nawaz