- •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 Використання завершуючих обробників виключень
1.7 Посилання та вказівники.
Операцiя адресацiї буде посиланням, якщо вона вжита в наступному контекcтi:
type &variablename=initexspression;
Тут variablename - це ідентифікатор змінної-посилання, що визначається, initexspression - це об’єкт, що має адресу в пам’яті(інколи використовується поняття L-вираз ). L-вираз (Lvalue-expression) - це вираз, що посилається на комірку пам’яті і тому має зміст в лівій частині бінарної операції присвоювання. Найпростіший приклад L-виразу є ідентифікатор вже визначеної змінної. Він посилається на комірку пам’яті, де зберігається значення цієї змінної. Посилання variablename визначає мiсце знаходження в пам'ятi iнiцiалiзуючого виразу.
Змiнна посилання повинна бути обов'язково iнiцiалiзованою. Оголошення виду Type & varname; не допускаються. Розглянемо наступний фрагмент програми:
int y=16;
int & x=y;
printf ("x=%d\n",x);
y=12;
printf ("x=%d\n",x);
Результат:
x=16
y=12
Оголошення int &x=y фактично визначає 2 ідентифікатора, що пов’язуються з однією і тою ж коміркою пам’яті. При зміні значення одного ідентифікатора змінюється значення і другого. Змінна x обробляється компілятором як звичайна змінна типу int. При звертанні до такої змінної немає потреби в операції зняття посилання чи яких-небуть інших дій. Очевидно, що описаний вище фрагмент програми можна було б переписати з використанням вказівників:
int y=16;
int *x=&y;
printf ("x=%d\n",*x);
y=12;
printf ("x=%d\n",*x);
Бачимо, що посилання суттєво відрізняються від вказівників.
Найчастiше посилання використовуються як формальнi параметри функцiй. Це робиться з двох основних причин:
а) для пiдтримки режиму зв'язування (аналог var в Pascal);
б) щоб не допустити копiювання змiнних в стек.
Розглянемо приклад:
void increment (int&x)
{x+=1;}
void increment (int*x)
{*x=*x+1;}
main()
{int v=3;
increment (v);
int anotherv=5;
increment (& anotherv);
printf ("v=%d\n",v);
printf ("anotherv=%d\n",anotherv);
}
Результати: v=4
anotherv=6
Конструкції int&x та int*x - це рiзнi сигнатури . Тому , з врахуванням можливості перевантаження функцій, вони можуть бути записані в одній області видимості. Проте , в прикладі викликатись буде спочатку перша функція ( в рядку increment (v);). Адже фактичним параметром її повинне бути посилання. Потім викликається друга , параметром якої є вказівник. Друга функція викличеться, очевидно, і в такій ситуації:
int *v1;
*v1=6;
increment (v1);
Використання посилань як формальних параметрiв функцiй має ряд особливостей. Розглянемо наступну програму:
void changev (int&p)
{p+=20;
printf ("значення p в функцiї =%d\n",p);}
main()
{int x=50;
changev (x);
printf ("x=%d\n",x);
int y=100;
changev (x+y);
printf("x=%d y=%d\n",x,y);
float r= -1.5;
changev (r);
printf ("r=%0.2f\n",r);
}
Результати:
значення p в функцiї =70
x=70
значення p в функцiї =190
x=70 y=100
значення p в функцiї =19
r=-1.50
Результат першого виклику функції changev в функції main() пояснюється елементарно. При виклиці функції changev(x+y) створюється локальна копія формального параметра , з якою працює функція (параметри передаються по значенню). В третьому випадку компілятор не може зв’язати посилання на тип int з змінною типу float. Тоді створюється тимчасова змінна, яка і зв’язується з р:
float r=-1.5;
int temp=r;
changev (temp);
Iнiцiалiзувавши посилання , йому не можна присвоїти iншi значення:
int ivar=12;
int &iref=ivar; /*Посилання на ivar*/
int anotherint;
iref=anotherint; // не допускається
Посилання можуть повертатися функцiями: double & ref (int d);.
Функцiї посилання використовуються для закриття внутрiшнього представлення структури даних.
Приклад:
#define FALSE 0
# define SIZE 100
#define BUFLEN 100
double & ref (int index);
void showarray (void);
double array [SIZE];
main ()
{int done=FALSE, index;
char buffer [BUFLEN];
for (index=0;index< SIZE;index++)
ref (index)=index;
while (!done)
{showarray();
cout<<"\n введiть index вiд 0 до 9\n";
cin.getline (buffer,buflen)
done=(strlen(buffer)= =0);
if (!done){
index=ataf(buffer); // перетворення рядка в число
cout<<"введiть значення типу float";
cin.getline (buffer,buflen); /*введення значення в буфер*/
ref (index)=ataf (buffer);
}
}
return 0;
}
double & ref (int index)
{if (index<0) index=0;
return array [index];}
void showarray (void)
{cont <<"\n array:\n";
for (int i=0;i< SIZE;i++)
cout <<"["<<i<<"]"<<array[i]<<'\n';}