У меня очень плохое понимание обработки исключений (например, как настроить операторы throw, try, catch для моих собственных целей).
Например, я определил функцию следующим образом: int compare(int a, int b){...}
Я бы хотел, чтобы функция генерировала исключение с некоторым сообщением, когда a или b отрицательны.
Как я должен подходить к этому в определении функции?
c++
exception-handling
Терри Ли
источник
источник
unsigned int
в качестве параметров в сигнатуре вашей функции. Опять же, я из школы, которую вы должны бросать и ловить исключения только для тех вещей, которые на самом деле исключительны.throw()
спецификации исключений для функций.Ответы:
Просто:
Стандартная библиотека поставляется с хорошей коллекцией встроенных объектов исключений, которые вы можете выбросить. Имейте в виду, что вы всегда должны бросать по значению и ловить по ссылке:
У вас может быть несколько операторов catch () после каждой попытки, так что вы можете обрабатывать разные типы исключений отдельно, если хотите.
Вы также можете повторно генерировать исключения:
И ловить исключения независимо от типа:
источник
throw;
(перебрасывать исходный объект и сохраняя его тип), а неthrow e;
(выбрасывать копию пойманного объекта, возможно, изменяя его тип).Просто добавьте,
throw
где необходимо, иtry
заблокируйте вызывающую программу, которая обрабатывает ошибку. По соглашению вы должны бросать только то, что происходит от васstd::exception
, поэтому включайте в<stdexcept>
первую очередь.Также загляните в Boost.Exception .
источник
Хотя этот вопрос довольно старый и на него уже дан ответ, я просто хочу добавить примечание о том, как правильно обрабатывать исключения в C ++ 11:
Используйте
std::nested_exception
иstd::throw_with_nested
Здесь и здесь в StackOverflow описывается , как вы можете получить обратную трассировку ваших исключений в вашем коде без необходимости в отладчике или громоздкой регистрации, просто написав соответствующий обработчик исключений, который будет перебрасывать вложенные исключения.
Так как вы можете сделать это с любым производным классом исключений, вы можете добавить много информации к такой обратной трассировке! Вы также можете взглянуть на мой MWE на GitHub , где обратная трассировка будет выглядеть примерно так:
источник
Вы можете определить сообщение, которое будет выдано при возникновении определенной ошибки:
или вы можете определить это так:
Как правило, у вас будет такой
try ... catch
блок:источник
Хотел ДОБАВИТЬ к другим описанным здесь ответам дополнительную заметку, в случае пользовательских исключений .
В случае, когда вы создаете свое собственное пользовательское исключение, которое происходит
std::exception
, когда вы перехватываете «все возможные» типы исключений, вы всегда должны начинатьcatch
предложения с «самого производного» типа исключения, которое может быть перехвачено. Смотрите пример (что НЕ делать):НОТА:
0) Правильный порядок должен быть наоборот, то есть - сначала вы,
catch (const MyException& e)
а затемcatch (const std::exception& e)
.1) Как вы можете видеть, когда вы запустите программу как есть, будет выполнено первое предложение catch (что, вероятно, вы НЕ сделали хотели в первую очередь).
2) Несмотря на то, что тип, перехваченный в первом предложении catch, имеет тип
std::exception
,what()
будет вызываться «правильная» версия - потому что она перехватывается по ссылке (измените, по крайней мере, перехваченныйstd::exception
тип аргумента на значение - и вы увидите явления «нарезки объектов» в действии).3) В случае, если «некоторый код из-за того, что исключение XXX было сгенерировано ...» делает важные вещи с ответом на тип исключения, здесь происходит неправильное поведение вашего кода.
4) Это также актуально, если захваченные объекты были «нормальными» объектами, такими как:
class Base{};
иclass Derived : public Base {}
...5)
g++ 7.3.0
в Ubuntu 18.04.1 выдает предупреждение, указывающее на упомянутую проблему:Опять же , я скажу, что этот ответ предназначен только для ДОБАВЛЕНИЯ других описанных здесь ответов (я думал, что этот момент стоит упомянуть, но не смог изобразить его в комментарии).
источник