- •2.1 Елементи концепції ооп .. 20
- •1.1 Коментарі.
- •1.2 Прототипи функцій.
- •1.3 Операція розширення області видимості.
- •1.4 Оголошення в операторах.
- •1.5 Перегрузка функцій.
- •1.6 Значення формальних параметрів по замовчуванню.
- •1.7 Посилання та вказівники.
- •1.8 Специфікатор inline
- •1.9 Операції new та delete .
- •1.10 Вказівник на void.
- •1.11 Зв’язування із збереженням типів
- •1.12 Про структури та об’єднання.
- •2.1 Елементи концепції ооп.
- •2.3 Опис протоколу класу.
- •2.4 Передача повідомлень об’єктам.
- •3 Функції-члени.
- •3.1 Функції-члени в межах та за межами формального опису класу.
- •3.2 Про вказівник this.
- •3.3 Перевантаження функцій-членів. Параметри по замовчуванню.
- •4. Конструктори та деструктори.
- •4.1 Поняття про конструктори.
- •4.2 Деструктори.
- •4.3 Досягнення високої ефективності. Конструктор копіювання.
- •5 Глобальні та локальні об’єкти.
- •6 Статична пам’ять та класи.
- •7. Наслідування
- •7.1 Синтаксична реалізація наслідування
- •7.2 Правила доступу до полів даних
- •7.3 Конструктори та деструктори в похідних класах
- •7.4 Використання заміщуючих функцій-членів.
- •7.5 Похідні класи та вказівники.
- •7.6 Ієрархія типів
- •7.7 Множинне наслідування
- •8 Вiртуальнi функцiї та класи
- •8.1 Віртуальні функції.
- •8.2 Чисті віртуальні функції. Абстрактні класи.
- •8.3 Віртуальні деструктори.
- •8.4 Посилання як засіб для реалізації поліморфізму
- •8.5 Технічна реалізація механізму віртуальних функцій.
- •8.6 Віртуальні базові класи
- •8.6.1 Ієрархії класів та наслідування
- •8.6.2 Віртуальні базові класи
- •8.6.3 Виклик конструкторів та віртуальні базові класи.
- •9 Друзі
- •9.1 Дружні класи.
- •9.2 Дружні функції.
- •10 Перевантаження операторiв.
- •10.1 Перевантаження операторів. Загальний підхід.
- •10.2 Перетворення типів.
- •10.3 Перевантаження деяких операторів.
- •10.3.1 Оператор індексування масиву.
- •10.3.2 Перевантаження оператора виклику функції.
- •10.3.3 Оператор доступу до члена класу.
- •10.3.4 Перевантаження операторів інкремента та декремента.
- •10.3.5 Перевантаження операторів управління пам’яттю (new,delete).
- •10.3.6 Перевантаження оператора присвоювання.
- •11.1 Функціональні шаблони
- •11.1.1 Визначення та використання шаблонів функцiй.
- •11.1.2 Перевантаження шаблонiв функцiї.
- •11.1.3 Cпецiалiзованi функцiї шаблона.
- •11.2 Шаблони класів.
- •11.2.1 Визначення шаблонів класу
- •11.2.2 Константи та типи як параметри шаблону
- •11.2.3 Використання шаблонних класів
- •11.2.4 Спецiалiзацiя шаблонiв класу.
- •11.3 Шаблони та конфiгурацiя компiлятора.
- •11.3.1 Шаблони Smart.
- •11.3.2 Шаблони Global I External.
- •12.2 Переадресація вводу-виводу
- •12.3 Розширення потоків для типів кориcтувача
- •12.4 Операції роботи з потоком як дружні
- •12.5 Форматований ввід-вивід
- •12.5.1 Ширина поля
- •12.5.2 Заповнюючий символ
- •12.5.3 Число цифр дійсних чисел
- •12.5.4 Прапорці форматування
- •12.5.5 Маніпулятори
- •12.6 Стан потоку
- •12.7 Файловий ввід-вивід
- •12.7.1 Конструктори файлових потокiв
- •12.7.2 Вiдкриття файлу
- •12.8 Неформатований ввід-вивід
- •12.9 Деякі функції вводу-виводу
- •12.10 Форматування в пам’яті
- •13 Управління виключеннями
- •13.1 Виключення та стек
- •13.2.1 Синтаксис основних конструкцій
- •13.2.1.1 Використання try та сatch
- •13.2.1.2 Використання throw
- •13.2.2 Тип виключення та конструктор копії
- •13.2.3 Пошук відповідного типу виключення
- •13.2.4 Використання terminate() та некеровані виключення
- •13.2.5 Робота з специфікаціями виключень
- •13.2.6 Робота з непередбаченими виключеннями
- •13.2.7 Робота з конструкторами та виключеннями
- •13.2.8 Динамічні об’єкти
- •13.2.9 Передача значень з конструктора та деструктора
- •13.2.10 Робота з ієрархіями виключень
- •13.2.11 Робота з специфічними класами виключень
- •13.3 Структурне управління виключеннями
- •13.3.1 Використання кадрованого управління виключеннями
- •13.3.1.1 Синтаксис
- •13.3.1.2 Про функцію RaiseException()
- •13.3.1.3 Фільтруючий вираз
- •13.3.1.4 Перехоплення виключення процесора
- •13.3.2 Використання завершуючих обробників виключень
5 Глобальні та локальні об’єкти.
Давайте підсумуємо інформацію про локальні та глобальні об’єкти, яка в тій чи іншій мірі вже зустрічалась вище .
Глобальні об’єкти.
Конструктори глобальних об’єктів викликаються до початку виконання функції main() в порядку їх слідування. Це забезпечує ініціалізацію всіх глобальних об’єктів класу до формального початку виконання програми - виклику функції main(). Деструктри глобальних об’єктів класу викликаються як звичайно в якості частини коду завершення програми, після відпрацювання всіх функцій завершення, заданих викликом функції atexit(). Деструктори не викликаються, якщо програма завершуєтьсмя за допомогою функції abort().
Локальні об’єкти .
Автоматичні об’єкти класу, оголошені локальними в функції, створюються разом з викликом функції та знищуються разом з завершенням її роботи. Автоматичні об’єкти зберігаються в стеці, як і звичайні автоматичні змінні. При завершенні роботи функції викликаються деструктори локальних об’єктів. Якщо програма завершується за допомогою виклику функції exit(), деструктори глобальних об’єктів викликаються як звичайно, а деструктори локальних об’єктів не викликаються. Приклад:
class empty{
char *obj_name;
empty(char*name)
public:
{cout<<“створений об’єкт з ім’ям”<<name<<“класу empty\n”;
obj_name=name;}
~empty()
{ cout<<“об’єкт з ім’ям”<<obj_name<<“знищений\n”;}
} one(“one”);
void main(void)
{empty second(“second”);}
Результати роботи програми:
створений об’єкт з ім’ям one класу empty
створений об’єкт з ім’ям second класу empty
об’єкт з ім’ям second знищений
об’єкт з ім’ям one знищений
Вказівники на об’єкти
Вказівники можуть посилатись на динамічні об’єкти , пам’ять для яких виділяється за допомогою операції new:
Ttime *ptoday;
ptoday=new Ttime;
В кучі виділяється область для об’єкту типу Ttime. Адреса першого байту цієї області присвоюється ptoday. Крім того, С++ викликає конструктор по замовчуванню, який ініціалізує об’єкт. Якщо необхідно виділити пам’ять та викликати інший конструктор, необхідно вказати відповідні параметри:
ptoday=new Ttime(9,14,1917,10,45).
Об’єкти-посилання
Об’єкти можуть оголошуватись як посилання. Нехай, наприклад, оголошений такий глобальний об’єкт :
Ttime today;
Тоді можемо визначити посилання
Ttime & rtoday=today;
rtoday-це посилання. Оскільки посилання посилається на вже існуючі об’єкти, при вході в область дії посилання конструктор класу не викликається і, відповідно, не викликається деструктор при виході з області дії.
Об’єкти-результати функцій.
Очевидно, що об’єкти , посилання на об’єкти та вказівники на об’єкти можуть виступати в якості аргументів функцій. Функція може і вертати об’єкт безпосередньо:
Ttime newtime(void)
{Ttime t;
return t;}
Тоді ця функція може викликатись так:
Ttime anothertime=newtime();
При цьому результат , який вертається функцією newtime() копіюється в anothertime. Правда, в нашому випадку це не логічно. Адже аналогічні дій виконуються при оголошенні : Ttime anothertime;
Часто використовують посилання на об’єкт чи вказівник на об’єкт в якості результату функції:
Ttime *newtime(void)
{Ttime *p=new Ttime;
return p;}
Тоді можна використати newtime() для отримання нового об’єкта та присвоїти його адресу вказівнику на Ttime:
Ttime*tp=newtime();
Функції-посилання можна використовувати для посилання на існуючі об’єкти:
Ttime today;-глобальний об’єкт
Ttime &newtimer(void)
{return today;}
Тоді можемо оголосити посилання на today так:
Ttime & tr=newtimer();
Звичайно, описані вище елементарні приклади є синтаксичною ілюстрацією.
Масиви об’єктів .
Масив об’єктів синтаксично задається як звичайний масив:
Ttime tentimes[10];
При цьому клас, екземпляри якого утворюють масив, повинен обов’язково мати конструктор по замовчуванню. Розглянемо приклад роботи з масивами об’єктів:
main(void)
{ Ttime tentimes[10];
for(int i=0;i<10;i++) tentimes[i].display();
return 0;
}
Очевидно, що тут буде надруковано 10 однакових значень.
Можна ініціалізувати масив , наприклад, так:
main(void)
{
Ttime tarray[3]={ Ttime(),Ttime(8),Ttime(8,1)};
for(int i=0;i<3;i++) tarray[i].display();
return 0;
}
Масиви об’єктів можуть розміщуватись в кучі та адресуватись за допомогою вказівників:
main()
{Ttime* tarrayp;
tarrayp=new Ttime[6];
for(int i=0;i<6;i++)
tarrayp[i].display();
delete[ ] tarrayp;
return 0;
}
Відмітимо, що в цьому прикладі 6 разів викликається конструктор по замовчуванню при виділенні пам’яті оператором new та 6 разів викликається деструктор при звертанні до delete, яка вжита в специфічній формі - з квадратними дужками (C++ ігнорує будь-які значення всередині цих дужок)
Контрольні запитання
1. Як викликаються конструктори глобальних об’єктів ?
2. Коли не викликаються деструктори локальних об’єктів при завершенні роботи програми ?
3. Навести приклад виділення пам’яті для екземпляра класу, що має лише конструктори з параметрами.
4. Коли не викликаються наявні конструктори при створенні екземпляра класу (і , відповідно, деструктори) ?
5. Чому при знищенні масиву об’єктів необхідно використовувати специфічну форму оператора delete ?
Завдання 5:
1. Описати масив об’єктів (що мають деструктори з відповідними повідомленнями) та проілюструвати роботу оператора delete:
delete a;
delete [ ] a;
delete &a[3];
delete &a[(int)(sizeof(a)/sizeof(a[0]))];
2. Написати функцію ret(), що має параметром індекс масиву об’єктів та повертає посилання на відповідний елемент.
3. Використовуючи функцію ret(), написати програму сортування масиву об’єктів за значеннями відповідних полів.
4. Модифікувати програми завдання 4.3( а)-б) ) так, щоб вони закінчувалася викликом функції exit(). Прослідкувати, як при цьому викликаються деструктори.
5. Розглянути ситуацію, коли програми попереднього завдання закінчується викликом функції abort().