Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Документ Microsoft Office Word 97 - 2003 (4).doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
540.67 Кб
Скачать

3. Const_cast (відкидання const або volatile)

Оператор const_cast використовується тільки, щоб зняти

атрибут const (або volatile) у об'єкту.

Зауваження: Вихідний об'єкт не повинен бути сталим. Якщо ж вихідний

об'єкт був оголошений як константний, результат зняття константності за допомогою

const_cast залежить від компілятора. Зазвичай це помилка часу виконання при

спробі зміни константного об'єкта через неконстантний покажчик.

Приклад:

class X {...};

void fun (X * p);

X x;

const X & sc = x; / / const посилання на НЕ const об'єкт

fun (& sc); / / Error! не можна передати покажчик на константу

fun (const_cast <X*> (& sc)); / / OK! зняли const, можна міняти

sc і x у функції

30. 1. dynamic_cast (перетворення + перевірка)

Оператоp ​​dynamic_cast реалізує приведення поліморфних типів (покажчиків або

посилань) в динамічному режимі.

Зауваження. Перетворення між об'єктами різних класів (в тому числі і

родинних) здійснюються за допомогою перетворень, визначених користувачем

- Конструкторів і операторів перетворення.

Далі, коли говоримо про приведення між класами, маємо на увазі роботу з посиланнями

або покажчиками на класи.

dynamic_cast <T*> (p) - перетворює p в тип T *, якщо * p дійсно

є об'єктом типу T, або типу класу, похідного від T,

інакше повертає 0.

dynamic_cast <T&> (p) - перетворює p в тип T &, якщо p дійсно

є об'єктом типу T, або типу класу, похідного від T,

інакше генерується виняткова ситуація bad_cast.

Зауваження. Можливо і перетворення у зворотний бік, з похідного в

базовий, але це перетворення виконується і неявно.

Зауваження. Спроба використати перетворення dynamic_cast для привидів типу

між неспорідненими поліморфними класами допустима. Результат: завжди

фіксується помилка приведення (0 або bad_cast).

Зауваження. dynamic_cast дозволяє робити приведення з віртуального поліморфного

(Тобто містить віртуальні функції) базового класу до похідного, чого звичайним

приведенням зробити не можна. Для неполіморфних віртуальних базових класів і

dynamic_cast не допоможе.

Приклад:

class Base {... virtual ...};

class Derived: public Base {...};

Base * bp, b_ob;

Derived * dp, d_ob;

bp = & d_ob; / / вказує на об'єкт похідного класу

dp = dynamic_cast <Derived*> (bp); / / OK

dp = dynamic_cast <Derived*> (& b_ob); / / 0, тому & B_ob не вказує

на об'єкт похідного класу.

При невдалій спробі приведення типів результатом виконання dynamic_cast

є 0, якщо в операторі використовувалися покажчики. Якщо ж використовувалися посилання,

генерується виняткова ситуація bad_cast.

Покажчик може мати нульове значення, тому при динамічному приведенні

покажчика у разі виникнення помилки може повертатись це нульове значення,

яке потім може бути перевірено в програмі. Помилка при приведенні посилання завжди

призводить до порушення виняткової ситуації bad_cast, тому що ніякого

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

приведення посилань завжди виконується перехопленням виняткової ситуації.

Приклад:

class A {... };

class B: public A {... };

class C: public A {... };

void f (A * p, A & r)

{B * pp;

if (pp = dynamic_cast <B *> (p))

{... / * Використання покажчика pp * /}

else {... / * покажчик pp не належить потрібному типу * /}

B & pr = dynamic_cast <B &> (r);

... / * Використання посилання pr * /

}

void g ()

{Try {f (new B, * new B); / / правильний виклик

f (new C, * new C); / / вихід в перехоплювач (C - з

інший ієрархії, заснованої на тому ж базовому класі)

}

catch (bad_cast)

{... / / Обробка виняткової ситуації

2. safe_cast

Оператор safe_cast є частиною Розширення компонентів Visual C + +. Він виконує перевірку типів під час виконання і створює виняток Platform :: InvalidCastException при неможливості перетворення. Використовуйте safe_cast, коли помилка часу виконання вказує на виняткові умови. Основне призначення safe_cast - допомогти у виявленні помилок програмування на етапі розробки і тестування в тому місці, де вони виникають. Обробляти винятки не слід, оскільки необроблений виняток сам визначає точку збою.

3. reinterpret_cast

Оператор reinterpret_cast використовується для небезпечних

перетворень, що залежать від реалізації. З його допомогою проводять

перетворення між покажчиками різних типів, між інтегральними

типами і покажчиками. Діє як Сі-приведення.

приклад:

char * s = ....;

long * lp = reinterpret_cast <long*> (s);

Зауваження: Для випадку множинного спадкоємства по результату дії

reinterpret_cast не збігається зі static_cast (збігається з Сі-приведенням).

приклад:

class A {int a; ...};

class B {int b; ...};

class C: public A, public B {int c; ...};

C c;

C * pc = &c;

B * pbs = static_cast <B*> (pc) ;/ / вказує на B в C

B * pbr = reinterpret_cast <B*> (pc) ;/ / вказує на початок

/ / Об'єкта C, тобто на A

C * pcs = static_cast <C*> (pbs); / / вказує на початок

/ / Об'єкта C, тобто на A

C * pcr = reinterpret_cast <C*> (pbs) ;/ / вказує на B в C

Об'єкт класу С

pc, pbr, pcs-> A: int a;

…..

pbs, pcr-> B: int b;

…..

C: int c;

31. Обробка виключних ситуацій

Виключна не передбачена ситуація або подія – це така ситуація яка призводить до не правильного виконання програми, до аварійної ситуації, до неправильної обробки данних.

Причинами виключних ситуацій можуть бути як зовнішні так і внутрішні чинники. Основною задачею виключних ситуацій є їх виявлення та обробка. Виключна ситуація це помилки в програмі. Для роботи з помилками ще в стандартному ANSI С було ряд засобів які дозволяли виявляти перехвачувати різні помилки в процесі програми також ANSI С були засобі які не приводили до завершення програми і дозволяли певним чином працювати. Для обробки виключних ситуацій в мові С використовують набір спеціальних функцій. В мові С++ спеціальні оператори під керування винятками розуміють стандартний інтерфейс для виняткових станів і подій виключення.

В мові С для керування виключеннями використовують SETJMP, LONGJMP, Matherr, new_handeer, які знаходяться в бібліотеці process.h and stdlib.h

Функції abort –це примусове завершення програми

Try Інструкції, які можуть порушувати винятки, повинні бути укладені в try-блок. Такий блок починається з ключового слова try, за яким йде послідовність інструкцій, укладена у фігурні дужки, а після цього - список обробників, званих catch-пропозиціями. Try-блок групує інструкції програми і асоціює з ними обробники винятків. Куди потрібно помістити try-блоки у функції main (), щоб були оброблені винятки popOnEmpty і pushOnFull?

for (int ix = 1; ix <51; + + ix) {

    try {/ / try-блок для винятків pushOnFull

if (ix% 3 == 0)

          stack.push (ix);

    }

    catch (pusOnFull) {... }

    if (ix% 4 == 0)

       stack.display ();

    try {/ / try-блок для винятків popOnEmpty

if (ix% 10 == 0) {

int dummy;

stack.pop (dummy);

stack.display ();

}

    }

    catch (popOnEmpty) {... }

}

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

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

catch (pushOnFull) {

    cerr << "trying to push value on a full stack \ n";

    return errorCode88;

}

catch (popOnEmpty) {

    cerr << "trying to pop a value on an empty stack \ n";

    return errorCode89;

}

Виключення та стек

У механізмі винятків C + +, переходить з виписки ходу до першої виписці catch, яка може обробляти пунктирна тип. Оператор catch при досягненні всі автоматичні змінні, що знаходяться в області блоку catch виписками між руху і знищуються в процесі, як очищення стека. У стеці розмотуючи, виконання триває таким чином:

Елемент управління досягається виписку try звичайним послідовним виконанням. Захищений розділ в блоці try виконання.

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

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

Якщо відповідний обробник як і раніше не знайдений або якщо виключення виникає під час очищення процесу, але до того, як обробник отримує елемент керування, стандартна функція середовища виконання terminate називається. Якщо виняток виникає після того, як виняток, але до початку очищення terminate викликаються.

Якщо відповідний обробник catch знайти, і воно перехоплює значення, то його формальний параметр ініціалізувати шляхом копіювання об'єкт винятки. Якщо воно перехоплює за посиланням, то параметр ініціалізації для посилання на об'єкт винятки. Після того як формальний параметр ініціалізації процес очищення стека. Це включає руйнування всіх автоматичних об'єктів, які були повністю будувати-, але ще не destructed-між початком блоку try, який пов'язаний з обробником catch і сайтом ходу винятку. Відбувається руйнування в зворотному порядку порядок розробки. Оброблювач catch відновлення виконання і виконання програми після останнього обробник-, що в перших виписці або проекту, відмінної від обробника catch. Елемент управління може увійти тільки обробник catch тільки через виключення, що виникає, виписку, ніколи не через перехід або мітку case в виписку switch.

32.

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

Виключна не передбачена ситуація або подія – це така ситуація яка призводить до не правильного виконання програми, до аварійної ситуації, до неправильної обробки данних.

Причинами виключних ситуацій можуть бути як зовнішні так і внутрішні чинники. Основною задачею виключних ситуацій є їх виявлення та обробка. Виключна ситуація це помилки в програмі. Для роботи з помилками ще в стандартному ANSI С було ряд засобів які дозволяли виявляти перехвачувати різні помилки в процесі програми також ANSI С були засобі які не приводили до завершення програми і дозволяли певним чином працювати. Для обробки виключних ситуацій в мові С використовують набір спеціальних функцій. В мові С++ спеціальні оператори під керування винятками розуміють стандартний інтерфейс для виняткових станів і подій виключення.

В мові С для керування виключеннями використовують SETJMP, LONGJMP, Matherr, new_handeer, які знаходяться в бібліотеці process.h and stdlib.h

Функції abort –це примусове завершення програми

У механізмі винятків C + +, переходить з виписки ходу до першої виписці catch, яка може обробляти пунктирна тип. Оператор catch при досягненні всі автоматичні змінні, що знаходяться в області блоку catch виписками між руху і знищуються в процесі, як очищення стека. У стеці розмотуючи, виконання триває таким чином:

Елемент управління досягається виписку try звичайним послідовним виконанням. Захищений розділ в блоці try виконання.

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

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

Якщо відповідний обробник як і раніше не знайдений або якщо виключення виникає під час очищення процесу, але до того, як обробник отримує елемент керування, стандартна функція середовища виконання terminate називається. Якщо виняток виникає після того, як виняток, але до початку очищення terminate викликаються.

Якщо відповідний обробник catch знайти, і воно перехоплює значення, то його формальний параметр ініціалізувати шляхом копіювання об'єкт винятки. Якщо воно перехоплює за посиланням, то параметр ініціалізації для посилання на об'єкт винятки. Після того як формальний параметр ініціалізації процес очищення стека. Це включає руйнування всіх автоматичних об'єктів, які були повністю будувати-, але ще не destructed-між початком блоку try, який пов'язаний з обробником catch і сайтом ходу винятку. Відбувається руйнування в зворотному порядку порядок розробки. Оброблювач catch відновлення виконання і виконання програми після останнього обробник-, що в перших виписці або проекту, відмінної від обробника catch. Елемент управління може увійти тільки обробник catch тільки через виключення, що виникає, виписку, ніколи не через перехід або мітку case в виписку switch.

Розкручення стеку

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