То, что вы, кажется, пойманы, является определенным адом того, кто пытается получить их пирог и съесть это также.
RAII и исключения предназначены идти рука об руку. RAII - это средство, с помощью которого вам не нужно писать много catch(...)
утверждений для очистки. Это произойдет автоматически, как само собой разумеющееся. И исключения - единственный способ работать с объектами RAII, потому что конструкторы могут только успешно или бросить (или поместить объект в состояние ошибки, но кто этого хочет?).
catch
Заявление может сделать один из двух вещей: обрабатывать ошибки или исключительные обстоятельства, или делать работу по очистке. Иногда это делает и то и другое, но каждое catch
утверждение существует для выполнения хотя бы одного из них.
catch(...)
неспособен сделать правильную обработку исключений. Вы не знаете, что является исключением; Вы не можете получить информацию об исключении. У вас нет абсолютно никакой информации, кроме того факта, что исключение было сгенерировано чем-то внутри определенного блока кода. Единственная законная вещь, которую вы можете сделать в таком блоке - это очистка. А это значит, что выкидывать исключение в конце очистки.
Что RAII дает вам в отношении обработки исключений, так это бесплатная очистка. Если все в RAII инкапсулировано правильно, то все будет правильно очищено. Вам больше не нужно, чтобы catch
заявления делали очистку. В этом случае нет причин писать catch(...)
заявление.
Так что я бы согласился, что catch(...)
это в основном зло ... временно .
Это положение является надлежащим использованием RAII. Потому что без этого вы должны быть в состоянии сделать определенную очистку. Там нет обойти это; Вы должны быть в состоянии сделать уборку. Вы должны быть в состоянии гарантировать, что бросок исключения оставит код в разумном состоянии. И catch(...)
это жизненно важный инструмент для этого.
Вы не можете иметь одно без другого. Нельзя сказать, что оба RAII и catch(...)
плохие. Вам нужен по крайней мере один из них; в противном случае вы не исключение.
Конечно, есть одно действительное, хотя и редкое использование, catch(...)
которое даже RAII не может изгнать: получение exception_ptr
перенаправления кому-то еще. Обычно через promise/future
аналогичный интерфейс.
Мои коллеги говорят, что вы всегда должны знать, какие исключения следует выдавать, и что вы всегда можете использовать такие конструкции, как:
Ваш коллега - идиот (или просто ужасно невежественный). Это должно быть сразу видно из-за того, сколько кода он предлагает вам скопировать и вставить. Очистка для каждого из этих операторов catch будет точно такой же . Это кошмар обслуживания, не говоря уже о читабельности.
Вкратце: это проблема, которую RAII был создан для решения (не то, что он не решает другие проблемы).
Что меня смущает в этом представлении, так это то, что большинство людей считают, что RAII - это плохо. Как правило, аргумент звучит так: «RAII - это плохо, потому что вы должны использовать исключения, чтобы сигнализировать о сбое конструктора. Но вы не можете генерировать исключения, потому что это небезопасно, и вам придется иметь много catch
операторов, чтобы все очистить». Что является ошибочным аргументом, потому что RAII решает проблему, которую создает отсутствие RAII.
Скорее всего, он против RAII, потому что он скрывает детали. Вызовы деструкторов не сразу видны на автоматических переменных. Таким образом, вы получаете код, который вызывается неявно. Некоторые программисты действительно ненавидят это. По-видимому, до такой степени, что они думают, что имеют 3 catch
оператора, и все они делают то же самое с кодом копирования и вставки - это лучшая идея.
...
» , а мой вопрос сосредоточиться на «Должен ли я лучше поймать...
или<specific exception>
перед тем Повторное выбрасывание»