Skip to content

Latest commit

 

History

History
148 lines (108 loc) · 9.07 KB

File metadata and controls

148 lines (108 loc) · 9.07 KB

Объектно-ориентированное программирование

Лабораторная работа №7. Обработка исключений


Теоретическая справка

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

Обработка исключений в С++ использует три ключевых слова: try, catch и throw. Те инструкции программы, где ожидается возможность появления исключительных ситуаций, содержатся в бло­ке try. Если в блоке try возникает исключение, т. е. ошибка, то генерируется исключение. Исклю­чение перехватывается, используя catch, и обрабатывается.

Try / Catch

try-catch - это механизм обработки исключений в C++, который позволяет обрабатывать ошибки и исключения, возникающие во время выполнения программы.

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

Синтаксис конструкции try-catch выглядит так:

try {
    // код, который может вызывать исключения
}
catch (exception_type1 exception_name1) {
    // код, который обрабатывает исключение exception_type1
}
catch (exception_type2 exception_name2) {
    // код, который обрабатывает исключение exception_type2
}
// ...
catch (exception_typeN exception_nameN) {
    // код, который обрабатывает исключение exception_typeN
}

В блоках catch указывается тип исключения и имя переменной, в которую будет сохранено исключение. В каждом блоке catch может быть написан код, который обрабатывает соответствующее исключение. Если исключение не было обработано в блоке catch, оно передается на обработку в вышестоящий блок catch, и так далее, пока не будет найден подходящий блок catch или пока исключение не достигнет функции main().

Пример:

#include <iostream>
#include <string>

int main() {
    try {
        std::string s = "Somebody ones told me";
        std::cout << s.at(69) << std::endl; // вызов исключения std::out_of_range
    }
    catch (std::out_of_range e) {
        std::cerr << "Caught an out_of_range exception: " << e.what() << std::endl;
    }
    return 0;
}

В этом примере мы вызываем исключение std::out_of_range в строке, которая выходит за границы строки s. Блок catch перехватывает это исключение и выводит сообщение об ошибке.

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

При выполнении первых лабораторных работ у многих вылетала программа, мало кто понимал почему, но чаще всего проблема была в неправильном преобразовании string в int.

Вот тут то нам и пригодится try / catch:

try {
    std::string line;
    std::getline(fin, line);

    auto f = split_line(line, ',');

    Films film;

    film.setRating(std::stoi(f[1]));

    result.push_back(film);

} catch(const std::exception &e) {
    std::cout << e.what() << std::endl;
}

В данном примере мы поместили кусок кода из readAll() функции в try-catch. Теперь он будет выполнятся, но если вдруг встретится ошибка, например, с stoi, о которой говорилось выше, то программа не сломается и продолжит свою работу, а мы получим сообщение о проблеме и сможем ее обработать или исправить.

Метод what() выдает нам что за ошибка произошла.

Throw

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

Когда throw вызывается, он создает исключение и передает его на уровень выше в стеке вызовов функций, где ищется обработчик исключений для данного типа исключения. Если обработчик не найден, исключение продолжает передаваться на уровень выше, пока не будет найден обработчик или пока не достигнут главный метод main(), где программа завершается с ошибкой.

double divide(double x, double y) {
    if (y == 0) {
        throw std::runtime_error("Division by zero");
    }
    return x / y;
}

int main() {
    double x = 10.0, y = 0.0;
    try {
        double result = divide(x, y);
        std::cout << result << std::endl;
    } catch (const std::exception& e) {
        std::cout << "Exception caught: " << e.what() << std::endl;
    }
    return 0;
}

Здесь мы определяем функцию divide(), которая делит число x на число y. Если y равно 0, то функция генерирует исключение типа std::runtime_error с сообщением "Division by zero". В главной функции main() мы вызываем функцию divide() с аргументами x = 10.0 и y = 0.0. Поскольку y равно 0, функция генерирует исключение, которое мы ловим в блоке catch. В этом блоке мы выводим сообщение об ошибке с помощью метода what() объекта исключения e.

Таким образом, использование throw позволяет обрабатывать ошибки в программе и делает код более надежным и устойчивым.

Еще пример:

try {
    bool TheEnd = false;
    if (TheEnd) 
        std::cout << "Congratulations! You've killed The Ender Dragon!" << std::endl;
    else 
        throw (TheEnd);
}
catch (bool achievement) {
    std::cout << "To obtain this achievemnet you have to kill The Ender Dragon!" << std::endl;
    std::cout << "Achievement status: " << achievement << std::endl;
}

Разберем пример:

В блоке try мы имеем переменную и условие, в случае, если условие не выполняется, то мы генерируем исключение с помощью throw и пробрасываем TheEnd.

Далее в дело вступает блок catch, который ее ловит, там мы и обрабатываем наше исключение, в данном случае выводим сообщение.


Задание

Сделать обработку исключений для чтения CSV файлов, при возникновении ошибки - в консоль передать номер строки, на которой возникла проблема.


Вопросы

  1. Что такое try
  2. Что такое catch
  3. Что такое throw
  4. Зачем применяют try / catch