- •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 Використання завершуючих обробників виключень
7.5 Похідні класи та вказівники.
Якщо похiдний клас derived має вiдкритий базовий клас base, то вказiвник на derived можна присвоювати змiннiй типу вказiвник на Base без використання явного перетворення типу. Обернене перетворення вказiвника на base у вказiвник на derived повинне бути явним.
Приклад:
class base {//....};
class derived : public base{//....};
derived m;
base * pb=& m; //неявне перетворення
derived * pd= pb; //
pd=(derived*)pb; // явне перетворення
Iншими словами, об`єкт похiдного класу при роботi з ним через вказiвник можна розглядать як об`єкт його базового класу. Обернене невiрно. Якщо base є закритим класом типу derived, неявне перетворення derivad* в base* не виконується, оскiльки до вiдкритого члена класу base можна звертатись через вказiвник на base але не можна через вказiвник на derived:
class base
{
int m1;
public:
int m2;
};
class derived : base
{
// m-закритий тип derived
};
...
derived d;
d.m2=2; //помилка
base*pb=&d; //помилка
pb->m2=2; //ok
pb=(base*)&a; // ok
pb->m2=2; // ok
7.6 Ієрархія типів
Похiдний клас сам може бути базовим.
Приклад:
class employee {...};
class secreturg : employee {...};
class manager : employee {...};
class tempoang : employee {...};
class consultant :tempoang {...};
class director : manager {...};
Як бачимо з класу base, при визначеннi конструктора допускається список iнiцiалiзацiї елементiв. Список iнiцiалiзацiї елементiв вiдділяється двокрапкою(:) вiд заголовка визначення функцiї i мiстить елементи даних (на базовi класи), роздiленi комами. Для кожного елемента вказується один чи кiлька параметрiв якi використовуються при iнiцiалiзацiї. Розглянемо два схожих класи з конструкторами. Перший використовує список iнiцiалiзацiї даних , другий - нi.
class XYValue
{
int x,y;
public:
XYValue(int_x,int_y):x(_x),y(_y)
{}
};
class XYData
{
int x,y;
XYData(int_x,int_y)
{
x=_x;
y=_y;
}
};
Хоча, для бiльшостi елементiв даних список iнiцiалiзацiй необов`язковий , вiн є єдиним методом iнiцiалiзацiї елементiв. Якщо елемент класу є об`єктом, то список iнiцiалiзацiй також буде для нього єдино-можливим механiзмом iнiцiалiзацiї.
7.7 Множинне наслідування
Досі ми розглядали просте наслiдування, тобо коли похiдний клас утворювався з одного базового. В С++ похiдний клас можна утворювати з кiлькох базових класiв. Множинне наслідування відрізніється лише тим, що похідний клас наслідує всі властивості базових.
Нехай А,B,С-деякi класи. Тодi похiдний вiд цих класiв оголошується так:
class D:public A,public B,public C
{ //. . .};
Аналогiчно як i в простому наслiдуваннi, вiдсутнiсть специфiкатора доступу по замовчуванню iнтепретується закритим специфiкатором(private).
Приклад:
class Coord
{protected:
int x,y;
public:
Coord(int_x=0,int_y=0);
void SetLoc(int_x,int_y);
Coord::Coord(int_x,int_y)
{SetColor(_x,_y);}
void Coord::SetLoc(int_x,iht_y)
{x=_x;
y=_y;}
class Message
{protected:
char msg[MAX_LEN];
public:
void SetMsg(char*msg)
{strcpy(msg,_msg);}};
Class Message XY:public Coord,public Message
{public:
void show( );
};
void Message XY::show( )
{ goto(x,y);
printf(msg); }
int main( )
{MessageXY greetng;
greeting.SetLoc(10,10);
greeting.SetMsg("Hellow");
greeting.Show( );
return 0;
};
У випадку конфлікта імен(наприклад, в двух базових класах оголошена функція-член з одним і тим самим іменем), необхідно використовувати операцію розширення області видимості для визначення необхідного нам члена класу:
Припустимо, що в двох базових класах оголошена функцiя з одним i
тим самим iм'ям:
class A
{protected:
int data;
public:
void func( void){//...}
};
class B{
public:
void func(void ){//...};
class C:public A,public B
{public:
int data;
//...}
int main(void)
{C c;
c.func( ) // помилка на етапi компiляцiї
с.data=10;
return 0;}
Вихiд з даної ситуацiї один - розширення областi видимості, тобто виклик функцiї func повинно здiйснюватися таким чином(в main):
int main(void)
{C c;
A::func( );
B::func( );
с.data=10;
return 0;}
Очевидно, що можна описати ще одну функцію, в якій вказати, яку з конфліктуючих функцій та коли викликати.
В класі, виведеному з кількох базових, може виникнути необхідність у виклику конструкторів цих класів. Якщо класи А, В, С мають конструктори по замовчуванню, в похідному класі D їх можна викликати наступним чином:
class D:public A,public B,public C{
public:
D( ):A( ),B( ),C( ){ }
//...};
Або ж конструктор можна оголосити так:
class D:public A,public B,public C{
public:
D( );
//...};
і реалізувати його за межами фомального опису класу:
D::D( ):A( ),B( ),C( ){ }
У базових класах можуть бути конструктори з параметрами. Вони викликаються аналогiчно як i в звичайному наслiдуваннi пiсля двокрапки при визначеннi конструктора. Конструктори в похiдному класi викликаються в тому порядку, в якому оголошенi базовi класи. Навіть якщо в конструкторі похідного класу вказати послідовність виклику іншою (відмінною від порядку слідування базових класів), це не вплине на результат.
Контрольні запитання
1. Як синтаксично реалізується наслідування ?
2. В чому полягає специфіка захищеної частини класу ?
3. Що таке заміщуюча функція-член ?
4. Яку властивість має вказівник на базовий клас ?
5. Що входить в список ініціалізації ?
6. Як можна ініціалізувати поля класу, використовуючи список ініціалізації в конструкторі?
7. Як реалізується множинне наслідування ?
8. Які небажані ситуації винкають при множинному наслідуванні ?
Завдання 7:
1.Перевiрити,чи вiдслiдкує компiлятор змiну порядку слiдування виклику конструкторiв базового класу.
2. Придумати приклад програми, коли результат залежить вiд порядку слiдування базових класiв.
3. Придумати приклад, коли виникає конфлікт імен при множинному наслідування.
4. Використовуючи клас Літак як базовий, утворити кілька класів літаків різних модифікацій (винищувач, бомбардувальник тощо), які відрізняються своїми характеристиками.
5. Використовуючи клас Океан , визначити клас Хижак та Жертва як похідні від нього. Визначити поле простір в класі Океан як масив вказівників на цей клас.
6. Описати класи Вірус та Плазмоклітина як похідні від класу Клітина. Плазмоклітина повинна вміти генерувати антитіла, вірус повинен вміти перетворювати звичайну сусідню клітину на вірусну, якщо сумарна потужність антитіл у ній менша від його потужності (або згідно з деяким іншим законом). Вірус повинен підвищувати температуру сусідніх звичайних клітин або плазмоклітин.
7. Описати клас База даних , в якому зберігається деяка інформація про працівників та визначаються похідні від нього для:
а) загального користування
б) нарахування заробітної плати
в) ФБР