Один из них заключается в использовании исключений C++: try catch blocks. Но освобождение динамической памяти будет проблемой при возникновении исключения .
@see RAII.
Исключения должны быть вашим предпочтительным методом решения исключительных ситуаций времени выполнения, таких как исчерпание памяти. Обратите внимание, что что-то вроде std :: map :: find не бросает (и это не должно), потому что не обязательно ошибка или особенно исключительный случай для поиска ключа, которого не существует: функция может сообщить клиенту, или нет. Это не похоже на нарушение предварительного условия или пост-состояния, такого как требование существования файла для правильной работы программы и определения того, что файла там нет.
Красота обработки исключений, если вы делаете это правильно (опять же, @see RAII), заключается в том, что она избегает необходимости выметать код обработки ошибок в вашей системе.
Рассмотрим случай, когда функция A вызывает функцию B, которая вызывает C, затем D и т. Д., Вплоть до «Z». Z - единственная функция, которая может бросать, и A является единственной, кто заинтересован в восстановлении от ошибки (A - это точка входа для операции высокого уровня, например, загрузка изображения). Если вы придерживаетесь RAII, который будет полезен для обработки исключений, тогда вам нужно будет поместить строку кода в Z, чтобы выбросить исключение и немного блока try/catch в A, чтобы поймать исключение и, скажем, отображение сообщение об ошибке пользователю.
К сожалению, многие люди не придерживаются RAII так строго, как должны на практике, поэтому в большом количестве кода реального мира есть больше блоков try/catch, чем это необходимо, чтобы справиться с ручной очисткой ресурсов (что shouldn ' t должен быть ручным). Тем не менее, это идеал, который вы должны стремиться достичь в своем коде, и это более практично, если это проект среднего размера. Аналогично, в реальных сценариях люди часто игнорируют коды ошибок, возвращаемые функциями. если вы собираетесь добавить лишнюю милю в пользу надежности, вы можете начать с RAII, потому что это поможет вашему приложению независимо от того, используете ли вы обработку исключений или обработку кода ошибки.
Существует предостережение: вы не должны бросать исключения через границы модулей.Если вы это сделаете, вы должны рассмотреть гибрид между кодами ошибок (как при возврате кодов ошибок, не используя глобальный статус ошибки, как errno) и исключения.
Стоит отметить, что если вы используете оператор нового в коде без указания nothrow везде, например:
int* p = new int(123); // can throw std::bad_alloc
int* p = new(std::nothrow) int(123); // returns a null pointer on failure
... то вы уже должны перехватывать и обрабатывать исключения bad_alloc в коде для того, чтобы быть надежным против исключений из памяти.
Используйте исключение для ИСКЛЮЧИТЕЛЬНЫХ ОШИБКОВ (http://stackoverflow.com/questions/180937/are-exceptions-really-for-exceptional-errors). Для обычных и повторяющихся ошибок вы можете попробовать новые объекты system_error в C++ 0x http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-1.html. Это ускорение. – anno
Вы должны использовать оба варианта. Какой из них зависит от ситуации. см. http://stackoverflow.com/questions/106586/what-are-the-principles-guiding-your-exception-handling-policy/106749#106749 –
anno: ссылка, на которую вы ссылаетесь, кажется, затрагивает само слово " исключительный ", что имеет для меня прекрасный смысл. В конце концов, вы не можете предсказать, какими будут общие ошибки. – Ken