Что бросать при броске C ++ исключений? - PullRequest
25 голосов
/ 28 февраля 2012

Это может быть глупым вопросом, но в C ++, когда я хочу вызвать исключение ... что я выбрасываю?

Должен ли я выдавать std :: exception или это зарезервировано?по стандартной библиотеке?Или я должен бросить строку или Int?Или я должен просто бросить все, что мне кажется уместным?

Ответы [ 5 ]

31 голосов
/ 28 февраля 2012

Бросить класс, полученный из std::exception;если вы #include <stdexcept>, вы можете выбрать из числа готовых, полезных производных классов.

Вывод из std::exception позволяет вашим обработчикам следовать распознаваемому стилю, как вы можетевсегда используйте .what(), чтобы получить текстовое сообщение.Не выбрасывайте примитивные типы, поскольку они не несут семантической информации.

8 голосов
/ 28 февраля 2012

Обычно люди не генерируют std :: exception напрямую по той простой причине, что он не хранит никаких сообщений об ошибках.Там не было бы ничего для того, что метод для возврата.Я иногда путаюсь из-за этого, потому что MSVC предоставляет нестандартное расширение для этого параметризованного конструктора в std :: exception, который принимает строку.

Вы можете выбрать один из существующих классов исключений, таких как std :: runtime_exception или определить свойсвоя.Это несколько субъективно, но я рекомендую свести количество классов исключений к минимуму, поскольку RAII может избавить от необходимости иметь много ветвей кода и блоков catch для разных типов исключений.Часто сообщения в сочетании с кодом, соответствующим RAII, достаточно для корректного восстановления после любого исключения.

И, наконец, я рекомендую все исключения, которые вы генерируете, наследовать от std :: exception по аналогичным причинам.Вам не нужно засорять свой код множеством разных блоков catch для разных типов исключений, если вы можете избежать этого.Решите проблему как можно чаще.

2 голосов
/ 28 февраля 2012

Основное исключение при выдаче чего-либо, полученного из std::exception, может быть, если вы используете какую-то инфраструктуру (например, MFC) с собственной иерархией исключений. В этом случае, как правило, вместо этого вы хотите получить производную от соответствующего места в их иерархии.

Обратите внимание, что я не особенно стараюсь держать MFC в качестве примера чистой обработки исключений (или чистого дизайна в целом), только пример структуры, которая включает иерархию исключений. Когда вы используете платформу, которая уже определяет иерархию исключений, вам, как правило, лучше ее использовать.

Другими словами, в отличие от предпочтения в C ++, в целом принято, что исключения должны представлять собой единую монолитную иерархию с одним корнем. Для стандартной библиотеки этот единственный корень - std::exception, но у других платформ есть альтернативы, и если они предоставляют такую, вы обычно хотите в нее вписать свою.

1 голос
/ 28 февраля 2012

В отличие от java, вы МОЖЕТЕ бросить все, что захотите (int, string, MyClass, ...).Но послушай Керрека.:)

0 голосов
/ 28 февраля 2012

Обычно вы хотите выбросить одно из исключений, полученных из std::exception, как говорили другие.

Иногда я выбрасывал другие типы, но только если он перехватывается в том же блоке изначение является чем-то полезным в этом контексте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...