Исключением является проблема, возникающая во время выполнения программы. Исключение C ++ - это ответ на исключительное обстоятельство, которое возникает во время работы программы, например попытка деления на ноль.
Исключения обеспечивают способ передачи контроля из одной части программы в другую. Обработка исключений C ++ построена на трех ключевых словах: try, catch
и throw
.
throw
- программа выдает исключение, когда возникает проблема. Это делается с использованием ключевого словаthrow
.catch
- программа выхватывает исключение с обработчиком исключений в месте в программе, где вы хотите справиться с этой проблемой. Ключевое словоcatch
указывает на отлов исключения.try
- блокtry
идентифицирует блок кода, для которого будут активированы определенные исключения. За ним следует один или несколько блоков catch.
Предполагая, что блок вызовет исключение, метод поймает исключение, используя комбинацию ключевых слов try
и catch
. Блок try/catch
помещается вокруг кода, который может генерировать исключение. Код внутри блока try/catch
называется защищенным кодом и синтаксисом для использования try/catch
следующим образом:
try {
// protected code
} catch( ExceptionName e1 ) {
// catch block
} catch( ExceptionName e2 ) {
// catch block
} catch( ExceptionName eN ) {
// catch block
}
Вы можете перечислить несколько операторов catch
, чтобы поймать разные типы исключений, если ваш блок try
вызывает более одного исключения в разных ситуациях.
Выбросы исключений
Исключения могут быть выброшены в любом месте блока кода с использованием инструкции throw
. Операнд оператора throw определяет тип исключения и может быть любым выражением, а тип результата выражения определяет тип созданного исключения.
Ниже приведен пример исключения исключения при делении на нулевое условие:
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
Устранение исключений
Блок catch
после блока try
выхватывает любое исключение. Вы можете указать, какой тип исключения вы хотите поймать, и это определяется объявлением об исключении, которое появляется в круглых скобках, следующих за ключевым словом catch
.
try {
// protected code
} catch( ExceptionName e ) {
// code to handle ExceptionName exception
}
Выше кода поймает исключение типа ExceptionName
. Если вы хотите указать, что блок catch должен обрабатывать любые исключения, которые выбрасываются в блок try
, вы должны поместить эллипсис ... между круглыми скобками, включающими объявление исключения, следующим образом:
try {
// protected code
} catch(...) {
// code to handle any exception
}
Ниже приведен пример, который генерирует деление на ноль, и мы поймаем его в блоке catch
.
#include <iostream>
using namespace std;
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
int main () {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
} catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
Поскольку мы создаем исключение типа const char *
, поэтому, поймав это исключение, мы должны использовать const char *
в блоке catch
. Если мы скомпилируем и запустим код выше, это приведет к следующему результату:
Division by zero condition!
Стандартные исключения C ++
C ++ предоставляет список стандартных исключений, определенных в <exception>
, которые мы можем использовать в наших программах. Вот небольшое описание каждого исключения, упомянутого в приведенной выше иерархии:
std::exception | Исключение и родительский класс всех стандартных исключений C ++. |
std::bad_alloc | Это может быть брошено new |
std::bad_cast | Это может быть вызвано dynamic_cast . |
std::bad_exception | Это полезное устройство для обработки неожиданных исключений в программе на C ++. |
std::bad_typeid | Это может быть вызвано typeid . |
std::logic_error | Исключение, которое теоретически можно обнаружить, прочитав код. |
std::domain_error | Это исключение, возникшее при использовании математически недопустимого домена. |
std::invalid_argument | Это вызвано неправильными аргументами. |
std::length_error | Это генерируется при создании слишком большой std :: string. |
std::out_of_range | Это может быть вызвано методом «at», например, std :: vector и std :: bitset <> :: operator [] (). |
std::runtime_error | Исключение, которое теоретически невозможно обнаружить, прочитав код. |
std::overflow_error | Это бросается, если происходит математическое переполнение. |
std::range_error | Это происходит, когда вы пытаетесь сохранить значение, выходящее за пределы допустимого диапазона. |
std::underflow_error | Это бросается, если происходит математическое недополнение. |
Определение новых исключений
Вы можете определить свои собственные исключения, наследуя и переопределяя функциональные возможности класса исключений . Ниже приведен пример, который показывает, как вы можете использовать класс std ::
exception для реализации своего собственного исключения стандартным способом -
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception {
const char * what () const throw () {
return "C++ Exception";
}
};
int main() {
try {
throw MyException();
} catch(MyException& e) {
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
//Other errors
}
}
Это приведет к следующему результату -
MyException caught
C++ Exception
Здесь what()
- это открытый метод, предоставляемый классом исключений, и он был переопределен всеми дочерними классами исключений. Это возвращает причину исключения.
Исключения работают почти одинаково во всех языках программирования. Поэтому не вижу ничего сложного в них.