67359

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

Лекция

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

Розглянемо механізми оброблення різних виняткових ситуацій. Виняткова ситуація (або виняток) – це помилка, яка виникає у процесі виконання програми. Використовуючи С++-підсистему оброблення виняткових ситуацій, такі помилки легко можна виправляти. Їх виникнення під час роботи коду програми автоматично...

Украинкский

2014-09-07

101 KB

6 чел.

Лекція № 22

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

План

  1.  Основні особливості оброблення виняткових ситуацій
  2.  Системні засоби оброблення винятків

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

    Розглянемо механізми оброблення різних виняткових ситуацій. Виняткова ситуація (або виняток) – це помилка, яка виникає у процесі виконання програми. Використовуючи С++-підсистему оброблення виняткових ситуацій, такі помилки легко можна виправляти. Їх виникнення під час роботи коду програми автоматично призводить до виклику так званого обробника винятків. При цьому програміст не забезпечує перевірку результату виконання кожної конкретної операції або функції "вручну". У цьому й полягає принципова перевага системи оброблення винятків, оскільки саме вона відповідає за код оброблення помилок, який раніше доводилося "вручну" вводити в громіздкі програми.

   Керування С++-механізмом оброблення винятків тримається на трьох ключових словах: try, catch і throw. Вони утворюють взаємопов'язану підсистему, у якій використання одного з них припускає застосування іншого. Спершу спробуємо отримати загальне уявлення про ті вигоди, які вони надають програмісту під час оброблення виняткових ситуацій. 

   Оброблення винятків-це системні засоби, за допомогоюяких программа може справитися з помилками тривалості виконання.

  1.   Системні засоби оброблення винятків

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

   Настанова throw генерує виняток, який перехоплюється catch-настановою.

   Отже, програмні настанови, у яких можливе виникнення виняткових ситуацій, мають виконуватися у межах try-блоку. Будь-яка функція, що викликається з цього try-блоку, також піддається контролю. Винятки, які можуть бути викинуті контрольованими настановами, перехоплюються catch-настановою, що йде безпосередньо за try-блоком, у якому фіксуються ці "викиди".

    

    Загальний формат try- і catch-блоків має такий вигляд:

try

{    

     // try-блок (блок коду програми, що підлягає перевірці на наявність помилок)

}   

catch(aType arg)

{

     // catch-блок (обробник винятків типу aType)

}

catch(bType arg)

{

     // catch-блок (обробник винятків типу bType)

}

catch(cType arg)

{

     // catch-блок (обробник винятків типу cType)

}

//....

catch(nType arg)

{

     // catch-блок (обробник винятків типу nType)

}

   Блок try повинен містити програмні настанови, який, на Вашу думку, мають перевірятися на предмет виникнення помилок. Цей блок може містити тільки декілька настанов певної функції або охоплювати весь код функції main() (у цьому випадку, по суті, "під ковпаком" системи оброблення винятків знаходитиметься вся програма).

   Після "викиду" виняток перехоплюється відповідною настановою catch, яка здійснює його оброблення. З одним try-блоком може бути пов'язана не одна, а декілька catch-настанов. Яка саме з них буде виконуватися, визначається типом винятку. Іншими словами, виконуватиметься та catch-настанова, тип винятку якої (тобто тип даних, який задається в catch-настанові) збігається з типом згенерованого винятку (а всі інші будуть проігноровані). Після перехоплення винятку параметр arg прийме його значення. Так само можуть перехоплюватися дані будь-яко-

го типу, в т.ч. об'єкти класів, що були створені програмістом.

Щоб виняток перехоплювати, необхідно забезпечити його «викид» в try-блоці.

   Загальний формат настанови throw має такий вигляд:

throw exception;

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

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

   Розглянемо простий приклад оброблення винятків засобами мови C++.

Приклад. Демонстрація механізму оброблення винятків

void main()

{

cout << "Po4atok" << endl;

 try

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

 cout << "Y try-bloci" << endl;

 throw 99;           // Генерування помилки

 cout << "Cja nastanova ne byde vukonana";

   }

 catch(int c)

{      // Перехоплення помилки

 cout << "Zna4ennja perehoplenogo vunjatky = : " << c << endl;

              }

cout << "Kinec programu";

}

  

   Внаслідок виконання ця програма відображає на екрані такі результати:

Початок.

У try-блоці

Значення перехопленого винятку дорівнює: 99

Кінець програми

 

   Розглянемо уважно код цієї програми. Як бачите, тут try-блок містить три настанови, а настанова catch(int c) призначена для оброблення винятку цілочисельного типу. У цьому try-блоці виконуються тільки дві з трьох настанов: cout і throw. Після генерування винятку керування передається catch-виразу, при цьому виконання try-блоку припиняється. Необхідно розуміти, що catch-настанова не викликається, а просто з неї продовжується виконання програми після "викиду" винятку. Стек програми автоматично налаштовується відповідно до ситуації, що виникла. Тому cout-настанова, що знаходиться після throw-настанови, ніколи не виконається.

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

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

Приклад.  Демонстрація не коректної роботи коду програми

void main()

{

cout << "Po4atok" << endl;

 try

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

 cout << "Y try-bloci" << endl;

 throw 99;           // Генерування помилки

 cout << "Cja nastanova ne byde vukonana";

   }

 catch(double c)

{      // Перехоплення помилки

 cout << "Zna4ennja perehoplenogo vunjatky = : " << c << endl;

              }

cout << "Kinec programu";

}

  Внаслідок виконання ця програма відображає на екрані такі результати:

Початок.

У try-блоці

Ця настанова не буде виконана.

  Такі результати виконання цієї програми пояснюються тим, що винятки ціло-

чисельного типу не перехоплює настанова catch(double c).

Тема: Використання функцій exit() і abort() 

   Функції exit() і abort() входять до складу стандартної бібліотеки C++ і їх часто використовують при програмуванні мовою C++. Обидві вони забезпечують завершення роботи коду програми, але відбувається це по-різному.

   Виклик функції exit() негайно приводить до "правильного" припинення роботи коду програми1. Зазвичай цей спосіб завершення роботи використовують для зупинки програми під час виникнення непоправної помилки, яка робить подальше її виконання безглуздим або небезпечним. Для використання функції exit() потрібно залучити до програми заголовок <cstdlib>. Її прототип має такий вигляд:

void exit(int status);

   Оскільки функція exit() викликає негайне завершення роботи коду програми, то вона не передає керування процесу, який її викликає, і не повертає ніякого значення. Проте процесу, що її викликає, як код завершення, передається значення параметра status. За домовленістю нульове значення параметра status вказує на успішне завершення роботи коду програми. Будь-яке інше його значення свідчить про те, що завершення роботи коду програми є помилковим. Для індикації успішного завершення роботи можна також використовувати константу EXIT_SUCCESS, а для індикації помилки – константу EXIT_FAILURE. Ці константи визначаються у заголовку <cstdlib>.

   Прототип функції abort() має такий вигляд:

 void abort();

   Функція abort() викликає негайне завершення роботи коду програми. Але, на відміну від функції exit(), вона не повертає операційній системі ніякої інформації про статус завершення роботи коду програми і не здійснює стандартної ("правильної") послідовності дій під час зупинки програми. Для використання функції abort() потрібно залучити до програми заголовок <cstdlib>. Функцію abort() можна назвати аварійним "стоп-краном" для С++-програми. Її необхідно використовувати тільки після виникнення непоправної помилки.

   Останнє повідомлення про аварійне завершення роботи коду програми (Abnormal program termination) може відрізнятися від наведеного в результатах виконання попереднього прикладу. Це залежить від використовуваного Вами компілятора. Виняток, що генерує функція, яку було викликано з try-блоку, можна перехопити цим самим try-блоком. Розглянемо, наприклад, таку цілком коректну програму.

Приклад. Демонстрація механізму генерування винятку функцією, що викликається з try-

                 блоку

void Xtest(int test)

{

cout << "У функції Xtest() значення test дорівнює: " << test << endl;

if(test) throw test;

}

void main()

{

cout << "Початок" << endl;

try

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

 cout << "У try-блоці" << endl;

 Xtest(0);

 Xtest(1);

 Xtest(2);

}

 

             catch(int c)

{      // Перехоплення помилки

 cout << "Значення перехопленого винятку дорівнює: ";

 cout << c << endl;

}

cout << "Кінець програми";

}

   Внаслідок виконання ця програма відображає на екрані такі результати:

Початок.

У try-блоці

У функції Xtest() значення test дорівнює: 0

У функції Xtest() значення test дорівнює: 1

Значення перехопленого винятку дорівнює: 1

Кінець програми

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

Приклад. Демонстрація механізму локалізації блоку try у рамках роботи самої функції

    // Функціонування блоків try/catch поновлюється під час кожного входження у функцію.

void Xhandler(int test)

{

try

{

 if(test) throw test;

}

catch(int c)  

{

 cout << "Перехоплення! Виняток №: " << c << endl;

}

}

void main()

{

cout << "Початок" << endl;

Xhandler(1);

Xhandler(2);

Xhandler(0);

Xhandler(3);

cout << "Кінець програми";

}

   Внаслідок виконання ця програма відображає на екрані такі результати:

Початок.

Перехоплення! Виняток №: 1

Перехоплення! Виняток №: 2

Перехоплення! Виняток №: 3

Кінець програми

   Як бачите, програма згенерувала три різних винятки. Після кожного винятку функція Xhandler() передавала керування у функцію main(). Коли вона знову викликалася, поновлювалося і оброблення винятків.

   У загальному випадку try-блок відновлює своє функціонування під час кожного входу в нього. Тому try-блок, який є частиною циклу, запускатиметься при кожному повторенні цього циклу.


 

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

52580. СХЕМА-МОДЕЛЬ ФУНКЦИОНАЛЬНО-СИСТЕМНОГО ПОДХОДА КАК ИНСТРУМЕНТ СИСТЕМАТИЗАЦИИ ЗНАНИЙ УЧАЩИХСЯ И ФОРМИРОВАНИЯ СИСТЕМНОГО И ТВОРЧЕСКОГО МЫШЛЕНИЯ 932.5 KB
  Отечественные и зарубежные ученые давно пытаются ответить на вопрос: каким должно быть образование, чтобы удовлетворять потребности современного мира? Почему во всем мире наблюдается глобальный кризис образования и какова основная функция школы нового тысячелетия.
52581. Усі уроки з інформатики 10 клас. Рівень стандарту 31.44 MB
  Вправи, що призначені для закріплення вивченого матеріалу, передбачають поступове наростання складності: знання теоретичного матеріалу, вміння використовувати його на практиці та застосування набутих знань у нестандартних ситуаціях
52582. Усі уроки фізики 10 клас. Академічний рівень 110.3 MB
  Закони збереження в механіці. Механічні коливання і хвилі. Релятивістська механіка. Молекулярна фізика і термодинаміка. Властивості газів, рідин і твердих тіл. Основи термодинаміки. Фізичний практикум
52583. Усі уроки екології 11 клас. Профільний рівень 127.74 MB
  Мінерально-сировинні ресурси: Особливості використання, екологічні проблеми. Тенденції зміни клімату. Водокористування та його екологічні наслідки. Екологічний стан землекористування. Стан вкористання і відтворення ресурсів рослинного і тваринного світу, екологічні проблеми.
52584. Усі уроки до курсу «Філософія». 11 клас. Профільний рівень 1.04 MB
  Філософське розуміння світу: бутт я, матерія. Людина та її бутт я у світі. Філософське розуміння душі, свідомості і розуму. Соціальна філософія. Пізнання та його основні форми. Філософія економіки. Духовне житт я суспільства. Філософія культури. Повторювально-узагальнювальний урок за темою «Духовне життя суспільства. Філософія культури»...