68959

Обробка виняткових ситуацій

Лекция

Информатика, кибернетика и программирование

Механізм обробки виняткових ситуацій в мові C++ заснований на трьох ключових словах: try, catch і throw. Фрагменти програми, що підлягають контролю, містять блок try. Якщо в ході виконання програми в блоці try виникає виняткова ситуація (тобто помилка), вона генерується...

Украинкский

2014-09-28

57 KB

4 чел.

Лекція № 21

Тема: Обробка виняткових ситуацій

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

Основи обробки виняткових ситуацій

Механізм обробки виняткових ситуацій в мові C++ заснований на трьох ключових словах: try, catch і throw. Фрагменти програми, що підлягають контролю, містять блок try. Якщо в ході виконання програми в блоці try виникає виняткова ситуація (тобто помилка), вона генерується за допомогою ключового слова throw. Потім виняткова ситуація перехоплюється блоком catch і обробляється. Уточнимо цей опис.

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

try {

// Тіло блоку try 

}

catch (тип1 аргумент)

{

// Тіло блоку catch 

}

catch (тип2 аргумент)

{

  // Тіло блоку catch 

} catch (тип3 аргумент)

{

// Тіло блоку catch 

}

 catch(munN аргумент)

{

// Тіло блоку catch 

}

Розмір блоку try може варіюватися. Він може містити як декілька операторів, так і цілу програму (в цьому випадку функція main() цілком поміщається в блок try).

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

Оператора throw має наступний вигляд.

throw виняткова_ситуація;

 

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

Якщо генерується виняткова ситуація, для якої не передбачена обробка, програма може припинити своє виконання. В цьому випадку викликається стандартна функція terminate (), яка за умовчанням викликає функцію abort (). Проте, як буде показано нижче, програміст може передбачити власну обробку помилки.

Розглянемо приклад, що демонструє обробку виняткової ситуації.

// Простій приклад обробки виняткової ситуації.

#include <iostream>

using namespace std;

int main() {

cout « "Початок\n";

try { // Початок блоку try

cout « "Усередині блоку try\n";

throw 100; // Генеруємо помилку.

cout << "Цей оператор не виконується.";

} catch (int i) { // Перехоплення помилки.

cout « "перехоплення виняткової ситуації - значення рівне: ";

cout « i « "\n";

}

cout « "Кінець";

return 0;

}

Ця програма виводить на екран наступні рядки.

Початок

Усередині блоку try

Перехоплення виняткової ситуації - значення рівне: 100

Кінець

Уважно проаналізуйте цю програму. Як бачите, блок try містить три оператори. З ним пов'язаний оператор catch (int i), що виконує обробку цілочисельної виняткової ситуації. Усередині блоку try виконуються тільки два з трьох операторів: перший оператор cout і оператор throw. При генерації виняткової ситуації управління передається операторові catch, а виконання блоку try припиняється. Інакше кажучи, блок catch не викликається. Просто програма переходить до його виконання. (Для цього стек програми автоматично оновлюється.) Таким чином, оператор cout, наступний за оператором throw, ніколи не виконується.

Зазвичай оператор catch намагається виправити помилку, роблячи відповідні дії. Якщо це можливо, виконання програми поновлюється з оператора, наступного за блоком catch. Проте часто помилку виправити неможливо, і блок catch припиняє виконання програми, викликаючи функцію exit () або abort ().

Як указувалося раніше, тип виняткової ситуації повинен співпадати з типом, вказаним в операторові catch. Наприклад, якщо в попередній програмі змінити тип аргументу оператора catch на double, перехоплення виняткової ситуації не відбудеться, і програма завершиться аварійно. Проілюструємо це наступним прикладом.

// Ця програма не працює.

#include <iostream>

using namespace std;

int main() {Початок\ п";

try { // Початок блоку try.

cout « "Усередині блоку try\n";

throw 100; // Генеруємо помилку.

cout << "Цей оператор не виконується";

} catch (double i) { // He перехоплює цілочисельні

// виняткові ситуації.

cout « "Перехоплення виняткової ситуації - значення рівне: ";

cout « i « "\n";

}

cout « "Кінець";

return 0;

}

У цій програмі оператор catch (double i) не перехоплює цілочисельні виняткові ситуації. (Зрозуміло, точний зміст повідомлення, що описує аварійне завершення програми, залежить від компілятора.) На екран виводяться наступні повідомлення.

Початок

Усередині блоку try

Abnormal program termination

Виключення може генеруватися поза блоком try тільки в тому випадку, якщо воно генерується функцією, яка викликається усередині цього блоку. Розглянемо приклад.

/* Генерування виняткової ситуації усередині функції, що знаходиться поза блоком try.

*/

#include <iostream>

using namespace std;

void Xtest(int test)

{

cout « "Усередині функції Xtest, test =: " « test « "\n";

if(test) throw test;

}

int main() {

cout « "Початок\ п";

try { // Початок блоку try.

cout << "Усередині блоку try\n";

Xtest(0);

Xtest(1);

Xtest(2);

} catch (int i) { // Перехоплення помилки.

cout << "Перехоплення виняткової ситуації - значення рівне: ";

cout « i « "\n";

}

 

cout « "Кінець";

return 0;

}

Ця програма виводить на екран наступні рядки.

Початок

Усередині блоку try

Усередині функції Xtest, test = 0

Усередині функції Xtest, test = 1

Перехоплення виняткової ситуації - значення рівне: 1

Кінець

Блок try може знаходитися усередині функції. В цьому випадку при кожному вході у функцію обробка виняткової ситуації виконується наново. Як приклад проаналізуємо наступну програму.

#include <iostream>

using namespace std;

// Блоки try/catch знаходяться усередині функції.

void Xhandler(int test)

{

try {

if(test) throw test;

} catch(int i){

cout « "Перехоплення виняткової ситуації #: " << i << ' \n';

}

}

int main() {

cout « "Начало\ п";

Xhandler(l); Xhandler(2);

Xhandler(O); Xhandler(3);

cout « "Кінець";

return 0;

}

Ця програма виводить на екран наступні повідомлення.

Початок

Перехоплення виняткової ситуації #: 1

Перехоплення виняткової ситуації #: 2

Перехоплення виняткової ситуації #: 3

Кінець

Як видимий, в ході виконання програми були перехоплені три виняткові ситуації. Після кожної обробки функція повертає управління зухвалому модулю. При повторному виклику функції обробка виняткової ситуації виконується знов.

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

#include <iostream>

using namespace std;

int main()

{

cout « "Початок\ п";

try { // Початок блоку try.

cout << "Усередині блоку try\n";

cout « "Все ще усередині блоку try\n";

} catch (int i) { // Перехоплення помилки

cout « "Перехоплення виняткової ситуації - значення рівне: ";

cout « i « "\n";

}

cout « "Кінець";

return 0;

}

Ця програма виводить на екран наступні повідомлення.

Початок

Усередині блоку try

Все ще усередині блоку try

Кінець

Як видимий, потік управління обійшов оператор catch стороною.


 

А также другие работы, которые могут Вас заинтересовать

42827. Разработка бункерно-ориентирующегося устройства для ориентации заготовок в пространстве и подачи их на станок 1.52 MB
  При применении автоматических механизмов питания подают штучные заготовки предварительно обработанные или необработанные полученные путем штамповки или методом точного литья; прутки предварительно калиброванные и рихтованные; бунтовую проволоку которую рихтуют в процессе подачи. 3 РАСЧЕТ РЕЖИМОВ РЕЗАНИЯ Станок: Бесцентровошлифовальный полуавтомат 3М184И Глубина шлифования t=004 мм; Диаметр шлифования d=14 мм; Продольная подача S=05 м мин; Скорость заготовки VЗ=60 м мин Эффективная мощность где СN=01; r=085; x=06; y=07; q=05 ...
42828. Проектирование двухступенчатого цилиндрического редуктора как составной части привода тяговой лебедки 700.26 KB
  От типа двигателя, его мощности, частоты вращения и прочего зависят конструктивные и эксплуатационные характеристики рабочей машины и её привода. Выбираем электродвигатель переменного тока с асинхронной частотой вращения короткозамкнутого ротора. Этот двигатель применяется потому
42829. Автоматизація технологічного процесу виробництва азотної кислоти комбінованим методом 328.31 KB
  Реле аварійного захисту КМ19 спрацьовує та створює аварійний сигналза допомогою якого повинно вимикатись живлення електродвигуна М7. Мікропроцесорний прилад ІТМ11 в якому використовується твердотільне реле через контакт якого не можна підключати напругу 220 В. Рекомендується через твердотіле реле ІТМ11 підєднувати електромагнітне реле яке працює на напрузі 24 В від джерела постійного струму. Враховуючи цю особливість в схемах електрозахисту треба використовувати два електромагнітних реле.
42830. Получение напайных и сменных многогранных режущих пластин путём прессования твердосплавных порошковых смесей и спеканием прессовок 5.77 MB
  Доминирующая роль в решении этой задачи принадлежит методам порошковой металлургии обладающими большими потенциальными возможностями с точки зрения создания инструментальных материалов различного назначения с заданными физикомеханическими свойствами изготовление которых методами традиционного металлургического передела во многих случаях практически неосуществимо. Подпись Дата Лист креплением СМП Фреза торцевая универсальная регулируемая с механическим креплением твердосплавных в том числе с износостойким покрытием безвольфрамовых и...
42833. Точные и высокопроизводительные металлорежущие станки, их расчет и основные характеристики 1.71 MB
  В частности к приводам главного движения и подач предъявляются требования: по увеличению жёсткости повышению точности вращения валов шпиндельных узлов. В большинстве станков в качестве привода главного движения применяют коробки передач со ступенчатым регулированием частоты вращения соединённые с асинхронным электродвигателем. Для обработки на станках деталей машин с разными размерами и режущим инструментом с различными режущими свойствами при большом числе технологических операций для получения оптимальных режимов резания необходимо...
42834. Організація аналітичного обліку розрахунків з постачальниками і підрядниками на КППНБМ 719.5 KB
  Теоретичні основи зобовязань що виникають з постачальниками і підрядниками.2 Нормативноправове регулювання з обліку зобовязань що виникають з постачальниками і підрядниками.3 Документування розрахунків з постачальниками і підрядниками. Синтетичний облік розрахунків з постачальниками і підрядниками на КППНБМ.
42835. Электронный измеритель временных интервалов в диапазоне от 0 до 1 с, с детализацией измерений до 1 мс 271.94 KB
  Для построения системы воспользуемся микропроцессорным комплектом К1810 (центральный процессор К1810ВМ88). Для реализации времязадающих функций воспользуемся таймером К1810ВИ54. Взаимодействие с пользователем организуем с помощью контроллера клавиатуры и индикации КР580ВВ79