Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

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

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

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

Предполагая, что блок может выбросить исключение, метод перехватывает его комбинацией try и catch. Блок try/catch помещается вокруг кода, который может сгенерировать исключение. Код внутри try/catch называется защищённым кодом. Синтаксис:

try {
    // защищённый код
} catch( ExceptionName e1 ) {
    // блок catch
} catch( ExceptionName e2 ) {
    // блок catch
} catch( ExceptionName eN ) {
    // блок catch
}

Можно перечислить несколько 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 {
    // защищённый код
} catch( ExceptionName e ) {
    // код обработки исключения ExceptionName
}

Этот код перехватит исключение типа ExceptionName. Если нужно, чтобы блок catch обрабатывал любой тип исключения, выбрасываемого в try, нужно поставить многоточие ... в скобках:

try {
    // защищённый код
} 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*, в блоке catch нужно использовать const char*. Результат:

Division by zero condition!

Стандартные исключения C++

C++ предоставляет список стандартных исключений, определённых в <exception>, которые можно использовать в программах. Они расположены в иерархии родитель-потомок:

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

Краткое описание каждого исключения:

№Исключение и описание
1

std::exception

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

2

std::bad_alloc

Может быть выброшено оператором new.

3

std::bad_cast

Может быть выброшено dynamic_cast.

4

std::bad_exception

Полезно для обработки неожиданных исключений.

5

std::bad_typeid

Может быть выброшено typeid.

6

std::logic_error

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

7

std::domain_error

Выбрасывается при использовании математически недопустимой области определения.

8

std::invalid_argument

Выбрасывается из-за недопустимых аргументов.

9

std::length_error

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

10

std::out_of_range

Может быть выброшено методом at, например у std::vector и std::bitset<>::operator[]().

11

std::runtime_error

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

12

std::overflow_error

Выбрасывается при математическом переполнении.

13

std::range_error

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

14

std::underflow_error

Выбрасывается при математическом недотеке (underflow).

Определение собственных исключений

Можно определить свои исключения, наследуясь и переопределяя функциональность класса exception. Пример использования 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) {
        // другие ошибки
    }
}

Результат:

MyException caught
C++ Exception

Здесь what() — публичный метод класса exception, переопределённый всеми дочерними классами исключений. Он возвращает причину исключения.

Язык C

  1. Освоение операторов C++: полное руководство с практическими примерами
  2. Комментарии в C++: лучшие практики для читаемого и поддерживаемого кода
  3. Шаблоны классов в C++: практическое руководство
  4. Работа с файлами в C: мастерство ввода-вывода с fopen, fprintf, fread и fseek
  5. Обработка исключений в Java: try, catch, finally, throw и throws
  6. Обработка исключений в C++: практические примеры try, catch, throw
  7. Мастерство обработки исключений в Python: эффективное использование try, except, finally и raise
  8. Обработка ошибок в C: лучшие практики и техники
  9. Язык программирования C++: обзор и ключевые особенности
  10. Константы и литералы в C++: типы, синтаксис и лучшие практики