Projektując moją pierwszą „poważną” bibliotekę C ++, zadaję sobie pytanie:
Czy to dobry styl czerpać wyjątki std::exception
i to jest potomstwo ?!
Nawet po przeczytaniu
Wciąż nie jestem pewien. Ponieważ, poza powszechną (ale może nie dobrą) praktyką, jako użytkownik biblioteki zakładam, że funkcja biblioteczna rzucałaby std::exception
tylko wtedy, gdy standardowe funkcje biblioteczne zawiodły w implementacji biblioteki, i nic na to nie poradzi. Ale mimo to, pisząc kod aplikacji, jest to dla mnie bardzo wygodne, a także IMHO dobrze wygląda po prostu rzucić std::runtime_error
. Również moi użytkownicy mogą polegać na zdefiniowanym minimalnym interfejsie, takim jak what()
lub kody.
I na przykład mój użytkownik podaje błędne argumenty, co byłoby wygodniejsze, niż rzucić std::invalid_argument
, prawda? Tak więc w połączeniu z powszechnym użyciem std :: wyjątku widzę w innym kodzie: Dlaczego nie pójść jeszcze dalej i wywodzić się z niestandardowej klasy wyjątków (np. Lib_foo_exception), a także z std::exception
.
Myśli?
lib_foo_exception
klasa wywodzi się std::exception
, użytkownik biblioteki łapałby lib_foo_exception
po prostu łapiąc std::exception
, oprócz tego, kiedy łapał tylko bibliotekę. Więc mógłbym również zapytać, czy klasa główna wyjątków mojej biblioteki dziedziczy po std :: wyjątek .
lib_foo_exception
?” Dzięki dziedziczeniu std::exception
możesz to zrobić przez catch(std::exception)
LUB catch(lib_foo_exception)
. Bez wywodzenia std::exception
złapałbyś go wtedy i tylko wtedy , gdycatch(lib_foo_exception)
.
catch(...)
. Jest tak, ponieważ język uwzględnia przypadek, który rozważasz (i biblioteki „źle zachowujące się”), ale to nie jest najlepsza współczesna praktyka.
catch
witryn, a także bardziej zgrubnych transakcji, które modelują operacje użytkownika końcowego. Jeśli porównasz to z językami, które nie promują idei uogólnionego łapania std::exception&
, np. Często mają o wiele więcej kodu z try/catch
blokami pośredniczącymi dotyczącymi bardzo specyficznych błędów, co nieco zmniejsza ogólną obsługę wyjątków, gdy zaczyna się umieszczać znacznie większy nacisk na ręczne zarządzanie błędami, a także na wszystkie różne błędy, które mogą wystąpić.
std::exception
nie znaczy rzucaćstd::exception
. Ponadtostd::runtime_error
dziedziczystd::exception
on po pierwsze, awhat()
metoda pochodzistd::exception
, a niestd::runtime_error
. I zdecydowanie powinieneś stworzyć własne klasy wyjątków zamiast generować wyjątki ogólne, takie jakstd::runtime_error
.