Универсальный обработчик
Часть раздела Логика и управление потоком путешествия по C++ на Coddy. Урок 52 из 56.
Иногда ваша программа might столкнуться с unexpected ошибками, которые не соответствуют конкретным типам exception, для которых вы подготовились. Универсальный обработчик catch catch(...) обеспечивает защиту, перехватывая любое exception, которое не было обработано вашими более конкретными блоками catch.
Универсальный обработчик использует три точки (...) вместо указания конкретного типа исключения. Он должен располагаться после всех остальных блоков catch, поскольку C++ проверяет их по порядку:
try {
// Код, который может выбрасывать различные исключения
} catch (std::invalid_argument& e) {
std::cout << "Invalid input!" << std::endl;
} catch (std::out_of_range& e) {
std::cout << "Number too large!" << std::endl;
} catch (...) {
std::cout << "An unexpected error occurred!" << std::endl;
}Обработчик catch-all действует как резервный вариант для любого типа exception, который не был пойман предыдущими blocks. Это особенно полезно при работе с кодом, который might throw exception, которые вы не предвидели, что гарантирует, что ваша программа не завершится из-за unexpected error.
Хотя в универсальном блоке catch нельзя получить доступ к конкретным сведениям об исключении, вы всё равно можете вывести общее сообщение об ошибке и выполнить операции очистки, чтобы программа продолжала работать без сбоев.
Задание
ЛегкоСоздайте программу, демонстрирующую комплексную обработку исключений с использованием нескольких блоков catch, включая универсальный обработчик. Эта задача проверит ваше понимание того, как обрабатывать как конкретные типы исключений, так и неожиданные ошибки, которые не подходят под заранее определённые категории.
Будут предоставлены следующие входные данные:
- Строка
testType, представляющая тип выполняемого теста ("string_convert","math_operation","array_access"или"unknown_error") - Строка
value1, которая будет использоваться как основные данные для операции - Строка
value2, которая будет использоваться как дополнительные данные для некоторых операций
Ваша программа должна:
- Создать функцию с именем
performTest, принимающую три строковых параметра - Внутри функции использовать структуру if-else для обработки разных типов тестов:
- Если testType равен
"string_convert": использоватьstd::stoiдля преобразования value1 в целое число и вывести его - Если testType равен
"math_operation": преобразовать и value1, и value2 в целые числа с помощьюstd::stoi, затем разделить value1 на value2 и вывести result - Если testType равен
"array_access": создать строку"Programming", преобразовать value1 в целочисленный index с помощьюstd::stoi, затем использоватьstr.at(index)для доступа к символу по этому index и вывести его. Метод.at()автоматически выбрасываетstd::out_of_range, если index недействителен: ручная проверка границ не требуется - Если testType равен
"unknown_error": выбросить целочисленное значение999 - В функции main вызвать
performTestвнутри блокаtry - Использовать несколько блоков
catchдля обработки исключений в следующем точном порядке: - Сначала:
std::invalid_argument&для недействительных преобразований строк в числа - Затем:
std::out_of_range&для слишком больших чисел или выхода index строки за границы - В-третьих:
catch(...)как универсальный обработчик для любых других типов исключений
Используйте следующий точный формат вывода:
Для успешных операций:
Success: [result_value]Для разных типов исключений:
Invalid argument caught
Out of range caught
Unknown exception caughtПомните, что универсальный обработчик catch(...) должен быть размещён последним, поскольку C++ проверяет блоки catch по порядку. Этот обработчик перехватит любой тип исключения, который не был обработан предыдущими специализированными блоками catch, включая целочисленное исключение, выброшенное в случае "unknown_error". Универсальный обработчик служит защитой от неожиданных ошибок, одновременно позволяя выполнять специализированную обработку известных типов исключений.
Попробуйте сами
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
// TODO: Напишите ваш код здесь - создайте функцию performTest
int main() {
// Чтение ввода
string testType;
string value1;
string value2;
cin >> testType;
cin >> value1;
cin >> value2;
// TODO: Напишите ваш код ниже - реализуйте блоки try-catch и вызовите performTest
return 0;
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Указатели и память
Что такое указатель?Оператор взятия адресаОператор разыменованияНулевые указателиУказатели и массивыДинамическая память и 'new'Освобождение памяти и 'delete'Итоги: Практика с указателями2Векторы (динамические массивы)
Знакомство с std::vectorСоздание вектораДобавление элементовДоступ к элементамРазмер вектораИтерация с помощью цикла ForRange-based цикл ForУдаление элементовИтоги: операции с векторами5Проект: Инструмент инвентаризации
Настройка проектаДобавление и обновление товаров8Основы обработки ошибок
Введение в исключенияБлоки 'try' и 'catch'Ключевое слово 'throw'Различные типы исключенийУниверсальный обработчикИтоги: Безопасное делениеПотренируйтесь самостоятельно: Онлайн-компилятор C++