Розробляючи свою першу "серйозну" бібліотеку C ++, я запитую себе:
Це гарний стиль отримувати винятки з std::exceptionпотомства ?!
Навіть після читання
Я досі не впевнений. Тому що, крім звичайної (але може не непоганої) практики, я б припустив, що як користувач бібліотеки, що функція бібліотеки кидає std::exceptions лише тоді, коли стандартні функції бібліотеки не вдаються до впровадження бібліотеки, і вона нічого не може з цим зробити. Але все-таки, коли пишуть код програми, для мене це дуже зручно, а також IMHO добре виглядає просто кинутиstd::runtime_error . Також мої користувачі також можуть розраховувати на визначений мінімальний інтерфейс, наприклад, what()або коди.
І, наприклад, мій користувач подає помилкові аргументи, що було б зручніше, ніж кидати std::invalid_argument, чи не так? Так що в поєднанні з ще поширеним використанням std :: винятку, який я бачу в інших кодах: Чому б не піти далі і виходити з вашого власного класу виключень (наприклад, lib_foo_exception), а також з std::exception.
Думки?
lib_foo_exceptionклас походить std::exception, користувач бібліотеки може спіймати lib_foo_exception, просто ловлячи std::exception, крім того, коли він ловить лише бібліотеку. Тож я також міг би запитати, чи повинен мої бібліотеки виключення root клас успадковувати від std :: виключення .
lib_foo_exception?" З успадкуванням від std::exceptionвас це можна зробити catch(std::exception)АБО by catch(lib_foo_exception). Не виходячи з цього std::exception, ви б його зловити, якби, і лише тоді , якщоcatch(lib_foo_exception) .
catch(...). Це є тому, що мова дозволяє використовувати випадок, який ви розглядаєте (і для "неправильно поводжуваних" бібліотек), але це не найкраща сучасна практика.
catchсайти, а також більш грубі транзакції, що моделюють операцію з кінця користувача. Якщо порівнювати його з мовами, які не сприяють ідеї узагальненого лову std::exception&, наприклад, вони часто мають набагато більше коду з посередницькими try/catchблоками, пов'язаними з дуже конкретними помилками, що дещо зменшує загальність поводження з винятками, коли вона починає розміщуватися набагато сильніше наголосити на ручному поводженні з помилками, а також на всіх різних помилках, які могли виникнути.
std::exceptionне означає , що ви кинутиstd::exception. Крім того,std::runtime_errorчи успадковуєтьсяstd::exceptionв першу чергу, іwhat()метод походитьstd::exception, неstd::runtime_error. І вам обов'язково слід створити власні класи виключень, а не викидати загальні винятки, такі якstd::runtime_error.