Учебники

Обработка исключений в C ++

Исключением является проблема, возникающая при выполнении программы. Исключение C ++ — это ответ на исключительное обстоятельство, которое возникает во время работы программы, например, попытка деления на ноль.

Исключения предоставляют способ передачи управления из одной части программы в другую. Обработка исключений в C ++ основана на трех ключевых словах: try, catch и throw .

  • throw — программа выдает исключение при обнаружении проблемы. Это делается с помощью ключевого слова throw .

  • catch — программа ловит исключение с помощью обработчика исключений в том месте программы, где вы хотите решить проблему. Ключевое слово catch указывает на перехват исключения.

  • try — блок try идентифицирует блок кода, для которого будут активированы определенные исключения. За ним следует один или несколько блоков улова.

throw — программа выдает исключение при обнаружении проблемы. Это делается с помощью ключевого слова throw .

catch — программа ловит исключение с помощью обработчика исключений в том месте программы, где вы хотите решить проблему. Ключевое слово catch указывает на перехват исключения.

try — блок try идентифицирует блок кода, для которого будут активированы определенные исключения. За ним следует один или несколько блоков улова.

Предполагая, что блок вызовет исключение, метод перехватывает исключение, используя комбинацию ключевых слов 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.

Live Demo

#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>, которые мы можем использовать в наших программах. Они расположены в иерархии родительско-дочерних классов, показанной ниже —

C ++ Иерархия исключений

Вот небольшое описание каждого исключения, упомянутого в приведенной выше иерархии:

Sr.No Исключение и описание
1

станд :: исключение

Исключение и родительский класс из всех стандартных исключений C ++.

2

станд :: bad_alloc

Это может быть брошено новым .

3

станд :: bad_cast

Это может быть брошено при помощи dynamic_cast .

4

станд :: bad_exception

Это полезное устройство для обработки неожиданных исключений в программе на C ++.

5

станд :: bad_typeid

Это может быть брошено typeid .

6

станд :: logic_error

Исключение, которое теоретически можно обнаружить, прочитав код.

7

станд :: domain_error

Это исключение, возникающее при использовании математически неверного домена.

8

станд :: invalid_argument

Это брошено из-за неправильных аргументов.

9

станд :: length_error

Выдается при создании слишком большой строки std ::.

10

станд :: out_of_range

Это может быть сгенерировано методом ‘at’, например, std :: vector и std :: bitset <> :: operator [] ().

11

станд :: runtime_error

Исключение, которое теоретически не может быть обнаружено путем чтения кода.

12

станд :: overflow_error

Это выбрасывается, если происходит математическое переполнение.

13

станд :: range_error

Это происходит, когда вы пытаетесь сохранить значение вне диапазона.

14

станд :: underflow_error

Это выбрасывается, если происходит математический недостаток.

станд :: исключение

Исключение и родительский класс из всех стандартных исключений C ++.

станд :: bad_alloc

Это может быть брошено новым .

станд :: bad_cast

Это может быть брошено при помощи dynamic_cast .

станд :: bad_exception

Это полезное устройство для обработки неожиданных исключений в программе на C ++.

станд :: bad_typeid

Это может быть брошено typeid .

станд :: logic_error

Исключение, которое теоретически можно обнаружить, прочитав код.

станд :: domain_error

Это исключение, возникающее при использовании математически неверного домена.

станд :: invalid_argument

Это брошено из-за неправильных аргументов.

станд :: length_error

Выдается при создании слишком большой строки std ::.

станд :: out_of_range

Это может быть сгенерировано методом ‘at’, например, std :: vector и std :: bitset <> :: operator [] ().

станд :: runtime_error

Исключение, которое теоретически не может быть обнаружено путем чтения кода.

станд :: overflow_error

Это выбрасывается, если происходит математическое переполнение.

станд :: range_error

Это происходит, когда вы пытаетесь сохранить значение вне диапазона.

станд :: underflow_error

Это выбрасывается, если происходит математический недостаток.

Определить новые исключения

Вы можете определять свои собственные исключения, наследуя и переопределяя функциональность класса исключений . Ниже приведен пример, который показывает, как вы можете использовать класс std :: exception для реализации вашего собственного исключения стандартным способом —

Live Demo

#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 () является открытым методом, предоставляемым классом исключений, и он был переопределен всеми дочерними классами исключений. Это возвращает причину исключения.