КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Оператори системи обробки критичних ситуацій
Систему обробки КС скаладають три оператори: throw, try i catch. Використання цих операторів дає можливість розширити вбудований механізм обробки КС на кожну окрему програмну ситуацію. Розглянемо ці оператори. Оператор throw. Виконання цього оператора генерує КС з посиланням інформаційного об’єкта про виключення. Розробнику програм найважливішим у цьому процесі є відсилання спеціалізованої інформації про виключення, а тому оператор throw називають оператором посилання КС. При цьому вважається, що збудником КС є зовнішній програмний блок. Наприклад, якщо оператор викликається з функції, то вважається, що, при виконання коду, КС згенерувала функція. Поза своїм основним призначенням оператор throw здійснює ще одне неявну додаткову дію: він уособлює КС об’єктом деякого типу. Це дає можливість генерувати КС як об’єкти найрізноманітніших типів, наприклад throw 1; // буде згенеровано КС цілого типу і послано // інформаційний об’єкт 1 «одиниця» цілого // типу про КС Throw «Bug»;// буде згенеровано КС стрічкового типу і // послано інформаційний стрічковий об’єкт // про КС class A {} // оголошення класу throw A (); // буде згенеровано КС класу А і послано // інформаційний об’єкт класу А про КС Окремим випадком є генерація бробляєає КС, наприклад throw; Такі КС не можуть бути перехопленими і відповідно обробленими, а тому призводить до виклику функції terminate () (див розд.10.3). Окремі компілятори дають можливість перехоплювати такі КС за допомогою встановлення нового обробника через функцію set_new_handler (). Оператор throw може викликатись явно, а може викликатись в тілі програмної конструкцій наприклад функції, класу тощо. Останній тип збудження КС називається неявним. В межах одного програмного блоку допускається декілька викликів операторів throw. Проте виконання першого з них призведе до генерації КС і виходу за межі програмного блоку з перериванням процесу виконання подальшого коду тіла блоку. Для функцій це є ще одним методом повернення з функції. Більше того за допомогою генерації КС формуються альтернативні значення функції (значення іншого типу), наприклад int F (int); main () { F (10); // згенерується виключення «exeption non zero» } int F (int i) { if (i) throw «exeption non zero»; // генерація else throw «exeption zero»; // стрічкових КС throw i; // генерація цілої КС return 10; // оператор return ніколи не виконається } В результаті виконання тіла програми згенерується КС «exeption non zero», а сама програма аварійно завершиться з повідомленням системного обробника КС «Abnormal program terminated». Наведений приклад ілюструє два важливі висновки: · функції можуть генерувати декілька КС різних типів; · перша генерація КС перериває подальше виконання тіла функція з відповідним очищенням стеку і є альтернативним механізмом повернення з тіла функції; · згідно синтаксису оголошення функція повертає лише одне (обмеження стандарту мови) значення, в даному випадку, цілого типу. За допомогою генерації КС вдається повернути значення іншого (стрінгового) типу. Тобто повертатиметься альтернативне значення, тобто значення іншого відмінного від синтаксичного оголошення типу. Таким чином долається вказане обмеження мови. Генерацією КС у функціях можна керувати. Це керування є визначальним для функції, які за своїм цільовим призначення повинні генерувати виключення. Суть цього керування полягає в тому, що розробник явно вказує типи КС, які дана функція може згенерувати. Загальний синтаксис виглядає так Тип Ім’я_функ (список_парам) throw (cписок_типів) Наприклад class A { public: int i; }; int F (int)throw (A); // обмеження генерації КС лише типом A main () { int i = F (0); // спроба згенерується недопустиме КС } int F (int i)throw (A) // усі спроби згенерувати КС не типу А { switch (i) // приведуть до аварійного завершення { case 0: throw «стрічкова КС»;break; case 1: throw A ();break; default: throw i; } } Наведений приклад не є зовсім вдалий, оскільки явно не ілюструє можливості генерування КС функціє F (). За оголошенням функції F () дозволяється генерувати КС лише типу А. Проте компілятор у наведеному коді не знайде помилки і бробляєаєт його. Будь-який виклик функції F () в період виконання програми призведе до аварійного завершення. Але породжуються ці аварійні завершення по різному. Так, якщо параметром функції F () передається відмінне від нуля значення, то аварійне переривання виконання програми спричинюється спробою згенерувати недопустиму КС. Якщо функції F ()передається нульове значення, то програма аварійно завершується лише тому, що згенерована КС ніде в програмі не перехоплюється. Зазначимо, що дозвіл генерування КС лише певного типу всередині тіла функції не стосується того випадку, коли згенерована КС іншого типу перехоплюється і обробляється всередині функції. Тобто правильним є такий код class A {}; F () throw(A) { try { throw 1; } catch (int i) { std::cout<<»Yes»;} } main () { F (); } Напротивагу цьому коду наступний є неправильним class A {}; F () throw(A) { throw 1; } main () { try { F (); } catch (int i) {cout<<»Yes»;} } Тобто список типів КС, які вказані у заголовку, визначає КС які функція може передавати назовні. Зарезервоване слово throw приведене в заголовку функції називається специфікацією КС. З метою заборони генерування функцією будь-якої КС список типів в директиві throw оголошення функції треба залишити порожнім, наприклад int F (int i) throw (); // функції забороняється // генерувати КС Якщо за сигнатурою функції не вказано жодного типу КС, то функція не може генерувати нові виключення, але може передавати далі виключення згенеровані функціями, які нею викликаються. Запис такої функції є таким int F (int i) throw; // функція передає КС Сучасні компілятори можуть підтримувати поширення КС бробляєає, а тому може бути відсутня потреба в явній декларації через сигнатуру функції поширення КС і достатнім є використання оператора з throw порожнім списком. Оператор try. Ідеологічно оператор throw або функція, яка може згенерувати КС, повинні виконуватись в тілі оператора try. Лише це дає можливість перехопити для обробки згенеровану КС. В противному випадку не існує способу перехопити КС в тілі програми, що, у свою чергу, призведе до аварійного завершення. Наявність оператора try визначає встановлення обробника КС. Тіло оператора try або блок try повинен містити ту частину програми, в якій необхідно відслідковувати помилки. Усе тіло функції main() може бути суцільним блоком try. Така програма дає можливість перехоплювати усі КС, які виникають в процесі виконання коду. Наприклад main () { try { ... // явна чи неявна генерація КС } ... //перехоплення і обробка КС } Генерація КС в тілі оператора try призводить до негайного завершення блока. Блоки try можуть бути вкладеними. При генерації КС у внутрішньому блоці, першим роботу завершує саме внутрішній оператор try. Особливістю оператора try є його нерозривний зв’язок з оператором сatch. Це обмеження є дійсним у всіх випадках. Функція також може містить блок try. Тоді при кожному входженні в тіло функції буде наново встановлюватись обробник КС. Єдиним обмеженням використання оператора try у функціях є його нерозривний зв’язок з оператором catch, який повинен зберігатись при побудові функцій. Оператор сatch. Оператори catch забезпечують обробку КС згенерованих оператором throw в тілі блока try. Тому їх називають користувацькими обробниками КС. Після генерації в межах дії оператора try КС перехоплюється відповідною інструкцією сatch, яка її обробляє. Це означає, що управління програмою неявно переходить до оператора сatch,а решта операторів, що залишилась після виклику throw, не виконується. Для одного блока try допускається існування цілої сім’я обробників КС. Важливим є їх негайне слідування за блоком try. Якщо оператор try викликається в тілі функції, то й оператори сatch також повинні знаходитись в цьому тілі. Iноді оператори сatch називають типова ними обробниками. Це визначається тим, що виклик конкретної з множини обробників інструкції сatch визначається типом КС. Тому для запуску обробника небхідно, щоб вказаний в інструкції сatch тип даних збігався з типом КС. При цьому усі решта обробників будуть проігноровані. Проглядаються обробники на збігання КС в порядку оголошень операторів сatch в програмі. Один обробник КС може обробити лише КС фіксованого типу. Це означає, що оператор сatch є унарним, тобто має лише один аргумент, і бробляєається в межах одного програмного блока існування декількох обробників КС одного типу. Параметр оператора сatch є локальним, тобто його областю дії є лише тіло обробника. Якщо значення КС розробника не цікавить, то параметр через який передається значення виключення обробнику може опускатись, наприклад catch (int) {cout<<»Yes»;} Наведемо повний приклад генерації і обробки КС #include <iostream> using namespaсe std; class A { public: int i; }; int F (int i) // ф-я генерує і бробляє КС { try { switch (i) { case 0: throw «стрічкова КС»;break; case 1: throw A ();break; case 2: throw i;break; default: throw 3 (задов.).14; } } catch(const char * c) // обробник рядк. КС разом зі значенням { cout<< c; } catch(A) // обробник усіх КС класу А { cout<<»об’єктна КС»; } catch(int) // обробник усіх КС цілого типу { cout<<»КС цілого типу»; } } main () { F (0); } Якщо згенеровано КС для якої немає відповідного обробника, то виключення перехоплюється вбудованим відлагодником. А це може призвести до аварійного завершення програми. Так у прикладі виклик F (4) спричинить аварійне завершення програми, оскільки обробник КС типу double не оголошено. Обробник може сам генерувати КС, або продовжити поширення вже існуючої (за допомогою генерації нової КС із значенням переданим через параметр оператора сatch), наприклад #include<iostream> main (int argc, char* argv[]) { try { try { throw 1; } catch(int i) { std::cout<<»Exception»; throw 3 (задов.).14; // Генерація нової КС } } catch(double i){ std::cout<<»Double Exception «;} catch(int i){ std::cout<<»Int Exception «;} }
Дата добавления: 2014-01-04; Просмотров: 438; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |