Эквивалент IllegalArgumentException из Java в C ++
-
22-08-2019 - |
Вопрос
В Java, если входной аргумент метода недопустим, мы можем выдать IllegalArgumentException
(который относится к типу RuntimeException
).В C ++ нет понятия проверенных и непроверенных исключений.Существует ли аналогичное исключение в стандартном C ++, которое может быть использовано для указания на исключение во время выполнения?Или существует общий стиль, которого нет в стандарте, но которому все следуют на практике в подобной ситуации?
Или я должен просто создать свое собственное пользовательское исключение и выбросить его?
Решение
В отличие от Java, C ++ не имеет "стандартной платформы", а лишь небольшую (и необязательную) стандартную библиотеку.Более того, среди программистов на C ++ существуют разные мнения о том, следует ли использовать исключения вообще.
Поэтому вы найдете разные рекомендации от разных людей:Некоторым нравится использовать типы исключений из стандартной библиотеки, некоторые библиотеки (напримерPoco) используют пользовательскую иерархию исключений (производную от std::exception), а другие вообще не используют исключения (напримерQt).
Если вы хотите придерживаться стандартной библиотеки, существует специализированный тип исключения: invalid_argument
(расширяет logic_error
).
#include <stdexcept>
// ...
throw std::invalid_argument("...");
Для справки:Вот обзор стандартных типов исключений, определенных (и документированных) в stdexcept
:
exception
logic_error
domain_error
invalid_argument
length_error
out_of_range
runtime_error
range_error
overflow_error
underflow_error
Другие советы
std::domain_error может быть тем, что вы ищете, но я подозреваю, что очень немногие люди используют его.Большинство людей выводят свои собственные типы исключений из std::exception .
Я всегда использую std::invalid_argument
за незаконные аргументы.
Если под недопустимым вы подразумеваете, что метод не удовлетворяет ожидаемым значениям, вы можете выбросить
std::logic_error
or
std::runtime_error.
Если вы имеете в виду что-то, связанное с приведениями, например, один объект не может быть преобразован в другой - для этого нет исключения, и оно не будет создано автоматически.
На самом деле так и будет. Но только для dynamic_cast<> по ссылкам.Это бросит
std::bad_cast
Я не уверен, что это хорошая идея - выкидывать это самостоятельно.
Я предпочитаю использовать logic_error и его производные на случай, если кто-то передал неправильный параметр, потому что это логическая ошибка:программист передал неправильный тип аргумента.
Но больше всего мне нравится использовать assert в таких случаях.Потому что такие вещи, как передача неправильных значений или типов вашей функции, могут быть приемлемы только во время разработки, и таких проверок следует избегать в выпуске.
Вы можете создать стандартное исключение или создать свое собственное.Возможно, вы захотите включить дополнительную информацию в создаваемое вами исключение, и это было бы хорошей причиной создать свое собственное.
Лично я не видел такой проверки домена в системах, над которыми я работал.Это, конечно, не универсально.