- •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 Використання завершуючих обробників виключень
10 Перевантаження операторiв.
10.1 Перевантаження операторів. Загальний підхід.
В С++ допускається перевантаження не лише функцій, як було показано вище, але і операторів. Така можливість надається при роботі з класами. Надалі не будемо акцентувати увагу на термінах оператор-операція, вважаючи їх тотожніми. Для перевантаження операторів використовується ключове слово operator. Щоб перевантажити оператор необхiдно описати функцiю такого виду:
<mun> operator <знак операцiї> (параметри).
Перевантажувати можна всi операцiї, крім “*”, “::”,” sizeof” та “.” .
По вiдношенню до класiв iснують два основних способи визначення перевантажених операторiв:
1. перевантаженi оператори оголошуються як функцiї дружнi до класу;
2. перевантаженi оператори є членами класу:
Приклад:
class complex{
double re, im;
public: complex (double r, double i)
{re=r, im=i;}
friend complex operator +(complex, complex);}
void ()
{complex a=complex (1,3.1);
complex b=complex (1.2,2);
complex c=b;
a=b+c; //(1)
c=a+complex (1,2);} //(2)
complex operator+(complex a,complex b);
{complex c;
c.re=a.re+b.re;
c.im=a.im+b.im;
return c;}
Замiсть (1)-(2) можемо записати:
а=operator + (b,c) ;
c=operator (a,complex(1,2));
Бачимо, що оголосивши перевантажений оператор + як дружню функцію до класу, можемо вільно використовувати значок “+” по відношенню до екземплярів класу. Причому в точках, де стоїть перевантажена операцiя, відбувається виклик функцiї оператора( в даному випадку оператор +). Очевидно, що компілятор буде розрізняти + перевантажений та + “звичайний”. Якщо десь буде фігурувати звичайний арифметичний вираз, то ніяких конфліктів не виникне. Іншими словами, перевантажуючи операції ми ніби розширюємо поле їх дії на відповідні екземпляри класів.
Перепишемо приклад таким чином, щоб перевантажений оператор був членом класу
class complex {
double re,im;
public:
complex (double r,double i)
{re=r; im=i;}
complex operator + (complex);
}
Бачимо, що в перевантаженому операторi + , на вiдмiну вiд попереднього прикладу, є один формальний параметр типу complex. Другий просто непотрібний. Адже в якості другого параметра виступає вказiвник на об'єкт this, для якого викликається функцiя-член.
Необхідно відмітити, що для перевантажених операторiв повинна обов’язково зберiгатись вихідна кiлькiсть операндiв:
class TStr {
private:
char val[12]
public:
TStr() {value [0]=0;}
TStr (const char *s);
long GetValue(void) {return atol(val);}
frend long operator + (TStr a, TStr b);
frend long operator - (TStr a, TStr b);
};
main()
{TStr a="1234";
TStr b="4321";
cout <<"\na+b+6="<<(a+b+6);
cout <<"\na-b+10="<<(a-b+10)<<'\n';
TStr : : TStr(const char * s)
{ strncpy (value, s, 11);
value [11]=0; }
long operator + (TStr a, TStr b)
{return (atol(a.value) + atol(b.value)); }
long operator - (TStr a,TStr b)
{return (atol(a.value) - atol(b.value));
Перепишемо цей приклад так, щоб перевантажені оператори були членами класу:
class TStr {
private:
char val [12]
public:
TStr () {value [0]=0;}
TStr (const char * s)
long GetValue (void) {return atol (val);}
long operator + (TStr b);
long operator - (TStr a);
};
main()
{TStr a="1234";
TStr b="4321";
cout <<"\na+b+6="<<(a+b+6);
cout <<"\na-b+10="<<(a-b+10)<<'\n';
retyrn 0;}
TStr : : TStr (const char * s)
{strncpy (value,s,11);
value [11]=0;}
long TStr ::operator + (TStr a, TStr b)
{return (atol(a.value) + atol(b.value));}
long TStr ::operator - (TStr a, TStr b)
{return (atol(a.value) - atol(b.value));}
Таким чином, як бачимо з наведених вище прикладiв, для будь-якої перевантаженої бiнарної операцiї @ вираз aa @ bb iнтерпретується як operator @ (aa,bb) чи aa. operator @ (bb) в залежностi вiд того, як визначена дана операцiя (функцiя-член чи функцiя друг). Звідси бачимо, що перевантажена функцiя-член не може мати перший параметр-елемент основного типу. Адже 2 @ aa iнтерпретується як 2.operator @ (aa) , що не допускається.
Аналогiчно для будь-якої унарної операцiї @ оператор aa@ чи @aa iнтерпретується як operator @(aa) чи aa. operator @ ().
Розглянамо приклад:
clas x {
friend x operator - (x);
friend x operator - (x,x)
friend x operator - ();// помилка
friend x operator - (x,x,x); // помилка
};