Стандартное или пользовательское исключение в C ++? - PullRequest
19 голосов
/ 20 января 2011

Для кода библиотеки лучше создать и выбросить пользовательский класс исключений (library :: Exception) или просто выбросить стандартные исключения (runtime_error, invalid_argument и т.

Ответы [ 4 ]

27 голосов
/ 20 января 2011

Обычно лучше специализировать (наследовать) стандартное исключение и выдавать его.

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

Также посмотрите это C ++ Faq о том, что бросить.

7 голосов
/ 20 января 2011

Обычно вы должны бросать экземпляры классов в заголовок stdexcept или его подклассы.Какой именно класс имеет смысл, зависит от конкретной проблемы.Я думаю, что бросать экземпляры «классов категорий» std::logic_error и std::runtime_error редко полезно, поскольку они не имеют присущего им значения;они используются для различения двух основных ситуаций, в которых могут возникать исключения:

  • Подклассы std::logic_error должны вызываться функцией, если она вызывается, но невсе предварительные условия выполнены.Исключением является ошибка вызывающего абонента, поскольку он не предоставил необходимые предварительные условия.Для этой категории вам обычно приходится выбирать между броском и неопределенным поведением;это компромисс между надежностью и эффективностью (например, std::vector::at() против std::vector::operator[]. Эти исключения часто не могут быть обработаны; они являются результатом ошибок в программе.

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

Я думаю, что доступные логика классы ошибок (например, invalid_argument) часто достаточно хороши, потому что, если они вызываются, код обычно должен быть исправлен, и нет никаких причин для сложных процедур обработки. С другой стороны, классы ошибок runtime в стандартной библиотекепо своей природе они гораздо менее гибки и охватывают в основном те области, где сама стандартная библиотека должна генерировать исключения.почти всегда может наследовать от этих классов ошибок времени выполнения.Например, класс, управляющий ресурсом операционной системы X , должен выдавать X_creation_error, который наследуется от std::runtime_error, если конструктору не удается выделить ресурс.

Часто полезно множественное виртуальное наследованиеза исключением классов.Вы можете наследовать от std::runtime_error или других stdexcept классов, от некоторого «класса маркера», специфичного для вашей библиотеки, и от boost::exception, чтобы получить дополнительные преимущества библиотеки Boost.Exception.Учебник Boost.Exception настоятельно рекомендуется, особенно Типы исключений в виде простых семантических тегов и Использование виртуального наследования в типах исключений .

2 голосов
/ 20 января 2011

Опыт показывает, что вам редко нужно больше, чем несколько классов исключений.

В большей части моего кода (в основном числовые - если вы делаете, например, IO, ситуация другая), я бросаю стандартные исключения (runtime_error, invalid_argument, ...), потому что они имеют тенденцию указывать на не может быть легко восстановлено из (кроме, возможно, invalid_argument), и которое, вероятно, не будет перехвачено пользовательским кодом (кроме, возможно, на верхнем уровне, чтобы бросить окно сообщения пользователю).

Если есть какое-то исключение, которое предназначено для перехвата типичным кодом пользователя, например. bad_custom_cast, или bad_market_data_identifier, вместо того, чтобы переходить к основному (как ошибка числовой процедуры или bad_alloc), я создаю пользовательский класс. Но на самом деле это довольно редко.

2 голосов
/ 20 января 2011

ИМХО Пользовательское исключение. Клиенты вашей библиотеки оценят это. Он будет знать, что именно вызывает исключение.

...