- •Шаблони класів
- •Конкретизація шаблону класу
- •Спеціалізація шаблонів класів
- •Статичні члени шаблонного классу
- •Ключове слово typename
- •Недоліки шаблонів
- •Обробка виняткових ситуацій
- •Генерування винятків
- •Перехоплювання винятків
- •Завдання до лабораторної роботи № 3
- •Об’єктно-орієнтоване програмування методичні вказівки
Ключове слово typename
Ключове слово typename можна використовцувати замість ключового слова class в оголошенні шаблону функції або класу.
Зауважимо тут, що можна змішувати ці ключові слова а оголошенні параметризованих типів шаблону. Наприклад:
template <typeneme Т, class S>
bool IsEmpty ();
З іншого боку, ключове слово typename може використовуватись для посилання на тип даних, який ще не визначений. Наприклад:
template <class Т>
void func ()
{
typedef typename T :: A ТА;
TA ta1;
typename T :: A ta2;
ТА * pta2;
}
Тут ключове слово typename використовується для оголошення змінних tal, ta2 і pta2 типу Т :: А, який ще не оголошений.
Недоліки шаблонів
Шаблони надають певні переваги при програмуванні, які пов’язані з широкою застосовністю коду і легким його супроводом. Загалом, цей механізм дозволяє вирішувати такі завдання, для яких використовується поліморфізм. З іншого боку, на відміну від макросів, вони дозволяють забезпечити безпечне використання типів даних. Проте з їх використанням пов’язані і деякі недоліки:
програма містить повний код для всіх породжених представників шаблонного класу чи функції;
не для всіх типів даних передбачена реалізація класу чи функції оптимальна.
Подолання другого недоліку можливе за допомогою спеціалізації шаблону.
Обробка виняткових ситуацій
Виняток – це деяка подія, яка є неочікуваною або перериває нормальний процес виконання програми. Стандарт мови С++ передбачає вбудований механізм обробки винятків. Крім того, компілятори Visual С++ 6.0 і Borland С++ Builder 5 передбачають ще один механізм обробки винятків, який реалізується в тісній взаємодії цих компіляторів з операційними системами Windows і Windows NT і називається структурованою обробкою винятків (SEH - від англ. Structured Exception Handling). Цей останний механізм був реалізований ще в компіляторах мови С, у зв’язку з чим часто називається С-винятками. Хоча структурована обробка винятків може бути використана в С++, для програм, написаних цією мовою, рекомендується використовувати більш новий механізм обробки винятків С++ (С++ ЕН від англ. С++ Exception Handling). Надалі ми будемо розглядати обробку винятків С++.
Механізм обробки винятків С++ реалізує так звану остаточну модель управління: після того як виняток відбувся, обробник винятку не може вимагати, щоб виконання було продовжено з того місця в коді, яке викликало виняток. Винятки С++ також не підтримують апаратних (або асинхронних) винятків: перехоплюються тільки винятки, викинуті деякою функцією. В контексті управління винятками в С++ використовуються три ключові слова: try, catch і throw.
Ключове слово try служить для позначення блоку коду, який може генерувати виняток. При цьому відповідний блок записується у фігурні дужки і називається захищеним, або try-блоком:
try
{
/ / Захищений блок коду
}
Тіло будь-якої функції, що викликається з try-блоку, також належить try-блоку. Передбачається, що одна або декілька функцій або інструкцій із захищеного блоку можуть викидати (або генерувати) винятки. Якщо викинуто виняток, виконання відповідної функції або інструкції припиняється, всі інші інструкції try-блоку ігноруються і керування передається поза блоком.
Ключове слово catch йде безпосередньо за try-блоком і позначає секцію коду, в яку передається управління якщо відбудеться виняток. За ключовим словом йде опис винятку, що складається з імені типу винятку і необов’язкової змінної, в круглих дужках:
catch (<тип_винят> <пер_винят>)
{
/ / Обробник винятку
}
Ім’я типу винятку ідентифікує обслуговуючий тип винятків. Блок коду винятку, який обробляється, записується в фігурні дужки і називається catch-блоком, або обробником винятку. При цьому говорять, що даний catch-блок перехоплює виняток описаного в ньому типу. Якщо виняток перехоплено, змінна <зм_винят> отримує його значення. Якщо Вам не потрібен доступ до самого винятку, вказувати цю змінну не обов’язково. Змінна винятку може мати будь-який тип даних, включаючи створені користувачем типи класів.
За одним try-блоком можуть йти кілька catch-блоків. Оператор catch, з вказаною замість типу винятку трикрапкою, перехоплює винятки будь-якого типу і має бути останнім з операторів catch, наступних за try-блоком.
Розглянемо простий приклад обробки винятків:
# іnclude <exceptipn>
# include <iostream>
using std :: cout;
void func ()
{
/ / Функція генерує виняток
}
int main ()
{
try
{
/ / Приклад використання механізму
/ / обробки винятків С + +
func ();
return 0;
}
catch (const char *)
{
/ / Обробник винятку типу const char *
cout << "Було викинуто виняток"
<< "типу const char * \ n";
return 1;
}
catch (...)
{
/ / Обробник всіх необроблених винятків
cout << "Було викинуто виняток"
<< "іншого типу \n";
return 1;
}
}
У розглянутому прикладі функція func () може генерувати винятки. У зв’язку з цим вона міститься в захищеному блоці. Перехоплення винятків здійснюється в двох catch-блоках. Перший з них перехоплює винятки, які мають тип const char, другий – будь-якого іншого типу.