Ошибки и обработка исключений (самомоднейшее C++)
В современных C++, в большинстве случаев предпочтительный способ сообщить и обработки ошибок времени выполнения и логических ошибок является использование исключений.Это особенно верно, когда стек может содержать несколько вызовов функций между функции, который обнаруживает ошибку и контекстом, чтобы знать, как его обрабатывать.Исключения позволяют формальных, четко кода обнаружения ошибок передачи данных вверх по стеку вызовов.
Ошибки программы обычно делятся на две категории: логических ошибок, вызванных программирования ошибки, например, сообщение об ошибке «индекс вне диапазона» и ошибок во время выполнения, выходящих за рамки управления программист, например, ошибка «сетевая служба недоступна».В стиле языка программирования и в модели COM отчетов об ошибках является управляемым, возвращая значение, представляющее код ошибки или код состояния для определенной функции или Установка общей переменной, вызывающий объект может при необходимости получить после каждого вызова функции, чтобы узнать, были ли о ошибках.Например программирования COM использует возвращаемое значение HRESULT для сообщения об ошибках для вызывающего объекта и Win32 API имеет функцию GetLastError, чтобы извлечь последнюю ошибку, произошедшую в стеке вызовов.В обоих случаях именно вызывающий код распознавать и реагировать на них соответствующим образом.Если вызывающий объект не явно обрабатывать код ошибки, программа может аварийно завершить работу без предупреждения или продолжить выполнение с неверные данные и неправильные результаты.
Исключения предпочтения в современном C++ по следующим причинам:
Исключение заставляет вызывающий код распознает ошибку и обработать его.Необработанные исключения остановить выполнение программы.
Исключение переходит к точке в стеке вызовов, можно обработать ошибку.Промежуточные функции позволяет распространять исключения.Они не имеют для координации с другими слоями.
Механизм очистки стека исключения уничтожает все объекты в области, четко определенные правила после генерации исключения.
Исключение позволяет четкого разделения между кодом, который обнаруживает ошибку и код, обрабатывающий ошибки.
Следующий упрощенный пример показывает синтаксис, необходимые для создания и перехвата исключений в C++.
#include <stdexcept>
#include <limits>
#include <iostream>
using namespace std;
class MyClass
{
public:
void MyFunc(char c)
{
if(c < numeric_limits<char>::max())
throw invalid_argument("MyFunc argument too large.");
//...
}
};
int main()
{
try
{
MyFunc(256); //oops!
}
catch(invalid_argument& e)
{
cerr << e.what() << endl;
return -1;
}
//...
return 0;
}
Исключения в C++ похожи в языках, таких как C# и Java.В try блока, если исключение исключение будет перехвачено в первом связанные catch блока, тип которого совпадает с исключением.Другими словами, выполнение переходит из throw инструкции для catch инструкции.Если блок catch можно использовать не найден, std::terminate вызывается и программа завершает работу.В C++ любой тип может быть создано исключение; Однако рекомендуется генерировать тип, который прямо или косвенно производным от std::exception.В предыдущем примере тип исключения invalid_argument, определенный в стандартной библиотеке в <stdexcept> файл заголовка.C++ не поддерживает и не требуется, finally блок, чтобы убедиться, что все ресурсы освобождаются, если создается исключение.Приобретение ресурсов — это идиому инициализации (RAII), которая использует смарт-указатели, обеспечивает необходимые возможности для очистки ресурсов.Дополнительные сведения см. в разделе Практическое руководство. Конструктор для исключения Безопасности.Сведения о механизм очистки стека C++ см. Исключения и стек разматывая в C++.
Основные правила
Обработка ошибок надежной является непростой задачей, на любом языке программирования.Хотя исключения предоставляет несколько возможностей, которые поддерживают хорошие обработки ошибок, они не могут делать всю работу для вас.Чтобы реализовать преимущества механизм обработки исключений, помните исключения при разработке кода.
Используйте утверждений для проверки ошибок, которые никогда не произойдет.Используйте исключения для проверки ошибок, которые могут возникнуть, например, ошибки проверки входных данных для параметров общих функций.Дополнительные сведения см. в разделе Exceptions VS. Assertions.
Используйте исключения, когда код, обрабатывающий ошибки может быть отделен от кода, который обнаруживает ошибку промежуточных вызовы функций.Следует ли использовать коды ошибок в важных для производительности циклов при код, обрабатывающий ошибку, тесно связаны с кодом, который определяет его.Дополнительные сведения о том, когда не следует использовать исключения см. When Not to Use Exceptions.
Для каждой функции, которая может создавать или распространять исключения, предоставляют один из трех исключение гарантий: надежные гарантии, основные гарантии или гарантии nothrow (noexcept).Дополнительные сведения см. в разделе Практическое руководство. Конструктор для исключения Безопасности.
Исключение по значению, перехватывать их по ссылке.Не catch не может обработать.Дополнительные сведения см. в разделе Рекомендации по создание и обработок исключения (C++).
Не используйте спецификации исключений, которые являются устаревшими в C ++ 11.Дополнительные сведения см. в разделе Exception specifications and noexcept.
Используйте стандартную библиотеку типов исключений при их применении.Производные типы исключений из класс исключения иерархии.Дополнительные сведения см. в разделе Практическое руководство. Использование объектов исключения стандартной библиотеки.
Не разрешать исключения покинуть деструкторов или освобождения памяти для функции.
Исключения и производительность
Механизм обработки исключений имеет очень минимальной производительности, затрат, если исключение не создается.Если создается исключение, стоимость обхода стека и очистки примерно сравним стоимость вызова функции.Требуются дополнительные структуры данных для отслеживания стека вызовов после try блок и необходимые дополнительные инструкции для раскрутки стека, если создается исключение.Однако в большинстве случаев стоимость, производительность и объем памяти не имеет значения.Скорее всего, будет значительно только в системах с очень ограниченным памяти неблагоприятное воздействие исключений на производительность или в важных для производительности циклы где ошибка, скорее всего, происходят регулярно и код для обработки он тесно связаны с кодом, который сообщает о.В любом случае невозможно знать фактические затраты исключений без профилирования и измерения.Даже в тех редких случаях, когда стоимость является существенным, вы можно сравнить от повышения правильности, проще поддерживаемость и другие преимущества, предоставляемые спроектированной исключения политики.
Исключения VS. утверждения
Исключения и утверждает являются два механизма обнаружения ошибок во время выполнения программы.Используйте утверждений для проверки условий во время разработки, никогда не должен иметь значение true, если ваш код правильно.Нет смысла в обработке такой ошибки с помощью исключения, так как сообщение об ошибке означает, что что-то в коде должно быть постоянным, а не представляют собой условие, которое программа восстановления во время выполнения.Метод assert останавливает выполнение в операторе, таким образом, можно проверять состояние программы в режиме отладки; исключение продолжает выполнение из первого соответствующего catch обработчика.Использование исключений для проверки условий ошибок, которые могут возникнуть во время выполнения, даже если код является правильным, например, «файл не найден» или "Недостаточно памяти.» Может потребоваться восстановление из этих условий, даже если восстановление просто выводит сообщение в журнал и завершает программу.Всегда проверяйте аргументы для общих функций с помощью исключения.Даже если функция без ошибок, не может получить полный контроль над аргументами, которые пользователь может передать его.
Исключения в C++ и исключения Windows SEH
Программы на c и C++ можно использовать структурированных исключений (SEH) механизм в операционной системе Windows.Понятия SEH схожи с исключениями C++, но использует SEH __try, __except, и __finally конструкции вместо try и catch.В Visual C++ исключения C++ реализуются для SEH.Тем не менее при написании кода C++ с помощью синтаксиса исключений C++.
Дополнительные сведения о SEH см. в разделе Структурная обработка исключений (C++).
Спецификации исключений и noexcept
Спецификации исключений были введены в C++ как способ указать исключения, которые могут вызывать функцию.Однако спецификации исключений бесполезной проблемных на практике и являются устаревшими в C ++ 11 стандарта.Мы рекомендуем не использовать спецификации исключений, за исключением throw(), указывает, что исключение позволяет без исключений для выхода.Если необходимо использовать спецификации исключений типа throw(Тип), имейте в виду, Visual C++ отходит от стандарта определенными способами.Дополнительные сведения см. в разделе Спецификации исключений.noexcept Спецификатор представлена в C ++ 11 как предпочтительной альтернативой throw().
См. также
Основные понятия
Практическое руководство. Интерфейс между исключительным и неисключительным кодом