Розділ №14. Підсумковий тест

  Юрій  | 

  Оновл. 30 Бер 2021  | 

 30

Ось ми і пройшли розділ «Винятки в мові С++», пора закріпити отримані знання.

Зміст:

Теорія

Обробка винятків забезпечує механізм відокремлення обробки помилок від загального потоку виконання коду. Це надає більше свободи для обробки помилок в кожній конкретній ситуації, зменшуючи більшість (якщо не всі) проблем, які виникають через використання кодів повернення.

Оператор throw використовується для викидання (генерації) винятку. Блоки try ловлять винятки, які викидаються в їх межах, і перенаправляють спіймані винятки блокам catch. Якщо тип винятку збігається з типом обробника catch, то обробник catch обробляє спійманий виняток.

Винятки обробляються негайно. Якщо виняток було викинуто, то точка виконання переходить до найближчого блоку try в пошуках обробника catch, який зможе обробити згенерований виняток. Якщо блок try не був знайдений або тип блоку catch не співпав, то стек почне розкручуватися до тих пір, поки не буде знайдено відповідний обробник catch. Якщо стек повністю розкручений, а обробник catch так і не знайдено, то програма завершить своє виконання з помилкою необробленого винятку.

Винятки можуть бути будь-якого типу даних, включаючи класи.

Блоки catch можуть обробляти винятки певного типу даних або відразу всіх типів даних — так звані «обробники catch-all», в яких еліпсис () вказується в якості типу винятку. Блок catch, який приймає об’єкт батьківського класу по посиланню, також перехоплюватиме і об’єкти дочірніх класів. Всі винятки, які викидаються Стандартною бібліотекою С++, є дочірніми класу-винятку std::exception (який знаходиться в заголовку exception), тому блок catch, приймаючи std::exception по посиланню, також оброблятиме всі інші винятки, які генеруються Стандартною бібліотекою С++. Метод what() використовується для конкретизації того, який тип std::exception було викинуто.

Всередині блоку catch може генеруватися новий виняток. Оскільки цей новий виняток викидається за межами блоку try, пов’язаного з цим блоком catch, то він не буде перехоплений поточним блоком catch (в якому виняток викинуто). Винятки можна повторно генерувати в блоці catch за допомогою ключового слова throw без вказівки будь-якого ідентифікатора. Не генеруйте повторно спійманий блоком catch виняток (об’єкт класу-винятку), таким чином ви зможете уникнути обрізки об’єкта.

Функціональні try-блоки використовуються для розміщення обробника винятків навколо всього тіла функції, а не тільки навколо її певної частини (блоку коду). Зазвичай вони використовуються тільки з конструкторами дочірніх класів.

Ніколи не генеруйте винятки всередині деструкторів.

Нарешті, обробка винятків має свою вартість. У більшості випадків код, який використовує виняток, працюватиме повільніше, а вартість обробки винятку відносно висока. Ви повинні використовувати винятки тільки для обробки виняткових ситуацій, а не в тривіальних випадках, в яких можна обійтися альтернативними методами (наприклад, стейтментами assert).

Тест

Напишіть клас Fraction, конструктор якого приймає чисельник і знаменник. Якщо користувач передав в якості знаменника 0, то викидайте виняток типу std::runtime_error (який знаходиться в заголовку stdexcept). У функції main() попросіть користувача ввести два цілих числа. Якщо числа, які ввів користувач, коректні, то виводьте створений об’єкт класу Fraction. Якщо ж числа некоректні, то ви повинні обробити виняток типу std::exception і повідомити користувачеві, що він ввів некоректні дані.

Підказка: std::runtime_error є дочірнім класу-винятку std::exception, тому у вас повинен бути тільки один блок catch.

Приклад виконання програми:

Enter the numerator: 7
Enter the denominator: 0
Your fraction has an invalid denominator.

Відповідь

Оцінити статтю:

1 Зірка2 Зірки3 Зірки4 Зірки5 Зірок (Немає Оцінок)
Loading...

Залишити відповідь

Ваш E-mail не буде опублікований. Обов'язкові поля відмічені *