Виключення та обробка помилок
Класифікація помилок:
- синтаксичні помилки
- логічні (результат неправильного розуміння та вирішення проблеми)
- виключення (виникають через незвиклі або передбачені проблеми. Приклади: недостатньо пам'яті, вихід за межі масиву, перебільшення значення числа, ділення на 0 та інші.)
В результаті виникнення помилок можливі варіанти:
- програма зависне
- видасть повідомлення та завершить роботу
- видасть повідомлення та надасть можливість продовжити роботу
- виправить ситуацію та продовжить роботу не турбуючи користувача
Обробка виключен в С++ включає перевірку типу та тегровані методи розв'язку незвиклих ситуацій. Виключенняце об'єкт що передається з області коду, де виникла проблема в область коду, де проблема обробляється. Тип виключення визначає яка область коду буде обробляти проблему. Вміст об'єкту може використовуватись для зворотнього зв'язку з користувачем. Основна ідея використання виключень:
- фактичний розподіл ресурсів відбувається на самому низькому рівні в програмі.
- логіка дій обробки виключень тісно пов'язна з кодом для взаємодії з користувачем
- виключення забезпечують швидкий перехід від ділянки коду, що розподіляє ресурси до ділянки коду, що обробляє помилку.
Основні етапи застосування виключень
1. Знайти ділянки коду, в яких можливі нестандартні ситуації, помістити їх в блок try.
2. Оргранізувати перехід на блок обробки виключення через ключове слово throw.
3. Для обробки виключень створити блок catch{...}, в якому виправляється ситуація, або видаються повідомленян користувачу.
Блок catch розміщується безпосередньо за блоком try. Таких блоків може бути декілька. Кожен з них визначається своїм іменем. Перехід на відповідний блок catch
void main()
{...
try{...F();
throw FileNotFound;
...
G();
Throw TooBig;
...
};
catch(FileNotFound){...}
catch(TooBig){...}
}
Тут передбачено два виключення: файл не знайдено і занадто велике значення. Кожне виключення обробляється відповідними блоком catch. Всі сучасні компілятори С++ підтримують можливість оброки виключень як вбудовану.
Обробка виключень
Виключення що передано попадає в стек викликів. Це список функцій що викликається. В ньому реєструється звернення до функції. Передане в стек виключення проходить всі його блоки поки не знайде свій блок обробки. Цей процес називається прокруткою стеку. Якщо передане виключення не знаходить відповідного блоку catch то викликається вбудований обробник, який завершить програму. Прокрутка стеку це процес незворотній. Програма поновить роботу після того блоку catch, який обробив дане виключення. Можлива ситуація коли причин виникнення виключення декілька. В цьому випадку блоки catch можна розмістити один за одним як в операторі switch. Еквівалентом частини default буде catch(...) , що означає обробити все.
class Array{
public:
int & operator[](int offSet);
class xBoudry{};
class xTooBig{};
...
};
int &Array::operator[](int offSet){
...
throw xBoundary;
...
throw xTooBig;};
void main(){
...
try {...};
catch(Array::xBoundary){...};
catch(...){...};
};
Виключення можуть бути об'єктамми, тому в межех класу де можливі незвиклі ситуації оголушуються класи виключень. При перевизначенні оператора [] можливий вихід за межі та ситуація надвеликого значення. Їм відповідають певні блоки catch. У випадку виникнення інших виключень спрацює блок catch{...} . Оскільки виключення це класи, для них діє принцип наслідування. При створенні виключень для роботи з шаблонами можливі 2 варіанти
- створити виключення всередині шаблону, тоді воно буде доступне всім екземплярам шаблону
- використовувати класи виключень, що створені назовні шаблону.
Шаблони
Механізм шаблонів С++ дозволяє використовувати типи в якості параметрів при визначенні класів або функцій. Шаблон залежить від тих властивостей параметру-типу які він використовує. Наприклад можна створити шаблон, який "навчить" компілятор створювати список для будь-якого типу аргументу. При використанні шаблонів тип елементу списку стає параметром для визначення класу. Інший приклад створити шаблон параметричного класу масивів, а при використанні його вказати тип об'єкту, що буде знаходитись в кожному екземплярі масиву. Отримані в результаті класи називають екземплярами шаблону. Параметричний шаблон створює загальний клас. Параметри шаблону дозволяють приписати конкретні властивості притаманні даному типу екземпляру. Перевантаження імені шаблону класу неможливе.
Оголошення шаблону.
Оголосимо шаблон для масиву, як параметричний об'єкт.
temlate <class T>
class Array
{public:
Array(){};
~Array(){};
private:
T * pType;
int Size;
};
Ключове словo tempate використовується на початку кожного оголошення для визначення класу шаблона. В кутових дужках перелічуються параметри шаблону, які змінюються в залежності від необхідного екземпляру. В прикладі буде змінюватись тип об'єктів що зберігаються в шаблоні масиву. На це вказує ключове слово class. Ідентифікатор T вказує на параметричний тип, який в одному екземплярі може бути цілим int, а в іншому типом класу наприклад Cat. Параметричний тип оголошується переважно в розділі private. Оголошення екземплярів шаблону відбувається при використанні шаблону наприклад функції main.
void main()
{ Array <int> intArray; //містить масив цілих чисел
Array <Cat> CatArray; //містить масив об'єктів класу Cat
};
Повна реалізація класу шаблона вимагає реалізацію конструктора копій, перевантаження операцій присвоєння та інше. Параментрами шаблону можуть бути одночасно параметри-типи, параметри вбудованих типів, та параметри шаблону.
temlate <class T, int; > class Cont{...};