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-блок, який є частиною циклу, запускатиметься при кожному повторенні цього циклу.


 

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

26600. СПОСОБЫ ОГЛУШЕНИЯ УБОЙНЫХ ЖИВОТНЫХ, ИХ СРАВНИТЕЛЬНАЯ ХАРАКТЕРИСТИКА 12.88 KB
  СПОСОБЫ ОГЛУШЕНИЯ УБОЙНЫХ ЖИВОТНЫХ ИХ СРАВНИТЕЛЬНАЯ ХАРАКТЕРИСТИКА. 2 способа: с оглушением и без оглушения. Животных других видов убивают без оглушения. К кольцу привязывают животное за рога чтобы в момент оглушения оно не отскочило назад.
26601. СТАНДАРТНАЯ СОРТИРОВКА ТУШ ПО УПИТАННОСТИ 15.96 KB
  Говядину взрослого скота молодняка а также баранину и козлятину подразделяют на 1ю и 2ю категории. Говядина 1й категории должна иметь как минимум удовлетворительное развитие мускулатуры; остистые отростки позвонков седалищные бугры и маклоки не должны резко выступать жировые отложения должны быть заметны в виде небольших участков на шее лопатках бедрах в тазовой полости и в области паха; слои подкожного жира от 8го ребра к седалищным буграм могут иметь значительные просветы. Говядина 2й категории характеризуется менее...
26602. СУЩНОСТЬ «ЗАГАРА» МЯСА. САНИТАРНАЯ ОЦЕНКА МЯСА ПРИ «ЗАГАРЕ». ЗАГАР 2.3 KB
  СУЩНОСТЬ ЗАГАРА МЯСА. САНИТАРНАЯ ОЦЕНКА МЯСА ПРИ ЗАГАРЕ. Это особый вид порчи мяса в первые сутки после убоя животного. Наблюдают его при недостаточно интенсивном охлаждении парного мяса а также при слабой аэрации если туши в парном состоянии плотно укладывают или тесно подвешивают одна к другой в душных помещениях при температуре выше 1520 С.
26603. СУЩНОСТЬ ПОНЯТИЙ «УСЛОВНО ГОДНОЕ МЯСО», «МЯСО ВЫНУЖДЕННО УБИТЫХ ЖИВОТНЫХ» 878 Bytes
  СУЩНОСТЬ ПОНЯТИЙ УСЛОВНО ГОДНОЕ МЯСО МЯСО ВЫНУЖДЕННО УБИТЫХ ЖИВОТНЫХ. Мясо вынужденно убитых животных мясо от больных животных лишенных жизни ввиду нецелесообразности или неэффективности дальнейшего лечения с целью недопущения падежа. Условногодное мясо мясо использование которого для пищевых целей допускается после обеззараживания.
26604. СУЩНОСТЬ ПРОЦЕССА ПОСОЛКИ И ГИГИЕНА ПОСОЛКИ МЯСА. ЗНАЧЕНИЕ И СУЩНОСТЬ ПОСОЛА 6.28 KB
  СУЩНОСТЬ ПРОЦЕССА ПОСОЛКИ И ГИГИЕНА ПОСОЛКИ МЯСА. Посол мяса один из самых древних ранее широко распространенных и доступных методов консервирования. В связи с развитием холодильной техники использованием высоких температур для консервирования мяса и мясопродуктов развитием колбасного производства посол уступил первое место этим методам консервирования. Однако и сейчас в сельской местности в личном хозяйстве он находит и будет находить применение как самостоятельный метод консервирования мяса н мясопродуктов.
26605. СХЕМА ИССЛЕДОВАНИЯ МЯСА НА ОБСЕМЕНЕННОСТЬ ВОЗБУДИТЕЛЯМИ ТОКСИКОИНФЕКЦИЙ 1.54 KB
  СХЕМА ИССЛЕДОВАНИЯ МЯСА НА ОБСЕМЕНЕННОСТЬ ВОЗБУДИТЕЛЯМИ ТОКСИКОИНФЕКЦИЙ. Схема бактериологического исследования мяса и мясопродуктов по ГОСТ 2123775.
26606. ТЕХНОЛОГИЯ УБОЯ КРС И ПЕРВИЧНАЯ ПЕРЕРАБОТКА ТУШ. ОГЛУШЕНИЕ. 22.62 KB
  ТЕХНОЛОГИЯ УБОЯ КРС И ПЕРВИЧНАЯ ПЕРЕРАБОТКА ТУШ. Чтобы предотвратить загрязнение туш и крови содержимым преджелудков на пищевод животным перед их обескровливанием накладывают лигатуру. Во избежание попадания крови от больных животных емкости нумеруют соответствующими номерами туш от которых собрана кровь. После этого полый нож извлекают из туши.
26607. ТЕХНОЛОГИЯ УБОЯ СВИНЕЙ И ПЕРВИЧНАЯ ПЕРЕРАБОТКА ТУШ. УБОЙ. ОГЛУШЕНИЕ 22.1 KB
  При сборе крови только для технических целей обычным боенским ножом производят глубокий разрез тканей в месте соединения шеи с грудной частью туши и направляя лезвие ножа вверх перерезают кровеносные сосуды у правого предсердия. Зачистка этих участков приводит к потерям массы туши и снижению ее товарного вида. Как указано выше свиные туши обрабатывают со съемкой шкур со съемкой крупонов и со шпаркой туш без съемки шкур. На конвейере вручную кольцеобразно подрезают гузенки снимают шкуру с бедер голяшек и паховой части от туш самцов...
26608. ТРАНСПОРТИРОВКА СКОРОПОРТЯЩИХСЯ ПРОДУКТОВ 8.39 KB
  ТРАНСПОРТИРОВКА СКОРОПОРТЯЩИХСЯ ПРОДУКТОВ. Главными задачами транспортировки являются быстрая доставка продуктов к местам назначения и сохранение их первоначальных качеств. Температурный режим при перевозке скоропортящихся продуктов В рефрижераторных поездах и секциях устанавливается в зависимости от температуры груза в момент погрузки. Совместная перевозка в одном вагоне разных видов скоропортящихся продуктов допускается при условии одинакового способа их обслуживания и на срок не превышающий установленного для наименее стойкого груза.