Я согласен с Raedwald в том, что если вы используете C ++ без очень осторожного стандарта кодирования, чтобы избежать EH (например: использовать nothrow new, избегать стандартных контейнеров и т. Д.), Что, как я полагаю, унаследованный код не сделал, тогда кодуже сломан и может протекать и делать спорадические вещи уже перед лицом исключений, с которыми он может уже встретиться, например bad_alloc
или bad_cast
, если вы полагаетесь на dynamic_cast
.
Тем не менее , с очень прагматичной точки зрения с унаследованной кодовой базой, есть вероятность, что унаследованный код справился с этим.И в конце концов, сколько нетривиальных приложений может изящно восстановиться после bad_alloc
исключений без очень явного контроля за распределением памяти?Не так много, и это не заставляет весь мир останавливаться.
Поэтому я на самом деле не рекомендую переписывать унаследованный код, чтобы попытаться перехватить исключения и везде использовать RAII.Вы можете использовать RAII здесь и там в коде, который вам абсолютно необходимо изменить, но я постараюсь найти причины, чтобы не менять его слишком сильно.Напишите тесты для этого и попытайтесь стабилизировать это и превратить это в черный ящик;библиотека функциональных возможностей, которая будет использоваться, не поддерживаться и изменяться при бесконечном блуждании по бесконечному LOC.
Теперь главная причина, по которой я здесь остановился и воскресил этот старый поток (извинения!), заключается в следующем комментарии:
Код обычно проверяет деление на 0 или проверяет NULL-указатели перед разыменованием.Но все равно бывает, что такой случай случится.Поскольку деление на ноль или разыменование нулевого указателя не вызывает исключение [...]
По моему сильному мнению, вы должны не бросать в ответ на такие вещи, как нольдоступ к указателю или деление на ноль, потому что это ошибки программиста .Если вы не работаете в критически важном программном обеспечении, в котором вы хотите изящно восстанавливаться, даже если в программном обеспечении есть ошибки, чтобы попытаться снизить риск жизни или что-то подобное, вы не хотите, чтобы приложение корректно восстанавливалось всобытие ошибок программирования.Причина, по которой вы обычно не хотите этого делать, заключается в том, что у нее есть обратная сторона: скрывать ошибки, делать их молчаливыми, позволяя пользователям игнорировать их и обходить их, а возможно, даже не удосуживаться сообщать о них.
Вместо этого для программистаошибки, которые вы, как правило, должны одобрять assert
, что вообще не связано с исключениями.Если утверждение не выполняется, программное обеспечение в отладочной сборке останавливается и, как правило, отображает сообщение об ошибке, сообщающее, где утверждение не удалось, вплоть до точной строки кода.Обычно это самая быстрая ставка для обнаружения и исправления этих ошибок программирования при запуске отладчика в ответ на сообщение об ошибке, поэтому не стесняйтесь свободно assert
.
Исключения наиболее полезны для внешних исключительных событий за пределамиуправление программистом.Примером может служить чтение файла, который оказывается поврежденным.Программист не может справиться с этим, поэтому его нужно выбросить и восстановить.Другой пример - не удается подключиться к серверу, пользователь нажимает кнопку сброса для операции, которая должна завершиться, и т. Д. Это исключительные внешние события ввода, а не ошибки программиста.
Лучший способ восстановления послеОшибки программиста, такие как доступ к нулевому указателю и деление на нули, - это сначала обнаружить их (assert
удобно), написать тест, чтобы воспроизвести его, исправить его и пройти тест, и назвать его днем, а не генерировать исключения и перехватыватьоставляя эти ошибки там.