
- •1 Парадигми та мови програмування
- •1.1 Процедурне програмування
- •1.2 Об'єктне (модульне) програмування
- •1.3 Об'єктно-орієнтовне програмування
- •2 Програмне середовище
- •3 Базові поняття програмування
- •4 Процедурно-орієнтоване програмування
- •4.1 Функції
- •4.2 Вбудовані (inline) функції
- •4.3 Передача параметрів
- •4.4 Обчислення значення функцій
- •4.4. Обчислення значення функції — вихід із функції; особливості повернення та використання іменованого значення, іменованої константи
- •4.5 Рекурсія
- •4.6 Довизначення (overloading) функцій
- •4.6. Довизначення (overloading) функцій
- •4.7 Узагальнені функції (function template)
- •4.8 Непряме використання функцій: указники на функції, їх тип, ініціалізація і присвоєння
- •4.9 Видимість
- •4.10 Тривалість життя об’єктів
- •5 Об'єктне програмування
- •5.1 Класи і об'єкти, члени класів
- •5.2 Інтерфейс класу, реалізація класу; визначення і оголошення класу
- •5.3 Створення і ініціалізація об'єктів, довизначення конструкторів, замовчуваний конструктор, копіювання, поверхневе і глибоке копіювання, ініціалізація і присвоєння, копіювальний конструктор
- •5.4 Cтатичні члени класів і статичні класні функції
- •5.5 Константні об'єкти, константні функції, змінювані члени константних об'єктів (mutable)
- •5.6 Поточний об'єкт this, указники на члени класу і класні функції, порівняння з указниками на (позакласні) функції, указники на статичні члени класу
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.7 5.8. Довизначення (overloading) операцій
- •5.8 Клас string: конструктори і присвоєння рядків, операції, відкладене копіювання
- •5.9 Параметризовані класи (class template): визначення шаблону, конкретизація
- •6 Об'єктно-орієнтовне програмування
- •6.1 Ієрархія об’єктів і ієрархія класів
- •6.2 Відкрите, закрите і захищене успадкування, успадкування типу і успадкування реалізації; абстрактні класи
- •6.3 Створення похідних об'єктів
- •6.4 Статичне і динамічне зв’язування
- •6.5 Успадкування із спільного базового класу. Кратне (multiple) успадкування. Віртуальне успадкування, порядок виклику конструкторів
- •7 Екзаменаційні завдання
- •7 Екзаменаційні завдання
5.7 5.8. Довизначення (overloading) операцій
Тепер об'єкт Item можна застосовувати як функцію, що даватиме його вартість
з урахуванням вказаної параметром ставки ПДВ,
int main()
{
Item theWhiteBook( 10.00 );
Item aBMW(60000.00);
//
cout << "Price of theWhiteBook " << theWhiteBook();
cout << "Price of a BMW” << aBMW( 20.00);
return 0;
}
Операція доступу до елементу масиву (індексування). За
її допомогою можна досягти кількох результатів. По-перше, це перевірка виходу
індексу за межі масиву. Ось приклад.
#include <iostream.h>
#include <string.h>
const short kMaxNameLength = 40;
class Name
{
private:
char namestring[ kMaxNameLength ];
short nameLength;
public:
class BadIndex{};
Name( char *name );
void operator()();
char& operator[]( short index );
};
Name::Name( char *name )
{
strcpy( namestring, name );
nameLength = strlen( name );
}
void Name::operator()()
{
cout <<namestring << "\n";
}
char& Name::operator[]( short index )
{
if ( ( index < 0 ) || ( index >= nameLength ) )
throw BadIndex();
return namestring[ index ];
}
Тут, між іншим, ми знову застосували функції-подібні об'єкти.
По-друге, індексування дає можливість створення асоціативних масивів. Ось
клас для підтримки асоціативного масиву пар
#include <iostream.h>
#include <string.h>
const short kMaxNameLength = 40;
class Name
{
private:
char namestring[ kMaxNameLength ];
short nameLength;
public:
class BadIndex{};
Name( char *name );
void operator()();
char& operator[]( short index );
};
Name::Name( char *name )
{
strcpy( namestring, name );
nameLength = strlen( name );
}
void Name::operator()()
{
cout <<namestring << "\n";
}
char& Name::operator[]( short index )
{
if ( ( index <0 ) || ( index >= nameLength ) )
throw BadIndex();
return namestring[ index ];
}
Приклад, що показує застосування асоціативного масиву,
int main()
{
Assoc a;
a.printAll();
a[string("weight")]=1.0;
a[string("high")]=2.0;
a[string("weight")]=3.0;
cout<<A[STRING("WEIGHT")]<<ENDL; pre < } 0; return a.printAll(); a[string(?foo?)]="100;" a[string(?area?)]='a[string("weight")]*a[string("high")];' cout<<a[string(?high?)]<<endl;>
Розумні указники (smart pointers). Якщо зліва від
знаку операції розіменування -> компілятор знаходить указника, то оператор
інтерпретується стандартним чином: виконується операція розіменування. Можна
довизначити розіменування так, щоб першим аргументом цього оператора став об'єкт
певного класу. Так довизначена операція повинна повертати указник. Якщо вона
повертає інший об'єкт, то в його класі знову ж повинна бути довизначене розіменування
і названий процес повторюється знову. Цей механізм називають розумним указником
(smart pointer). Розіменування проходить ланцюжок обєктів, аж поки на
його шляху не зустрічається справжній указник.
#include <iostream>
#include <string>
using namespace std;
const short kMaxNameLength = 40;
class Name
{
private:
char first[ kMaxNameLength ];
char last[ kMaxNameLength ];
public:
Name( char *lastName, char *firstName );
void DisplayName();
};
Name::Name( char *lastName, char *firstName )
{
strcpy( last, lastName );
strcpy( first, firstName );
}
void Name::DisplayName()
{
cout << "Name: " << first << " " << last;
}
class ComputerScientist
{
private:
Name* namePtr;
short age;
public:
ComputerScientist( Name *namePtr, short age );
Name* operator->();
};
ComputerScientist :: ComputerScientist(Name* n, short a )
{
this->namePtr = n;
this->age = a;
}
Name* ComputerScientist::operator->()
{
return( namePtr );
}
int main()
{
Name thePascalAuthor( "Wirth", "Niklaus" );
ComputerScientist Wirth( &thePascalAuthor, 67 );
Wirth->DisplayName();
return 0;
}
Операції, які ми щойно розглянули, взаємозалежні. Дійсно якщо p указник типу
T T* p , то
p->m == (*p).m == p[0].m
Сюди ж належать також операції інкременту і декременту, якщо їх застосовувати
для адресної арифметики. Ось приклад, що ілюструє застосування розумного указника
типу Time
class PtrToTime
{
Time* current;
Time* array;
int size;
public:
class BadIndex{};
PtrToTime(Time *v, int s);
Time* operator->();
Time& operator* ();
Time& operator[](int i);
PtrToTime& operator++();
PtrToTime operator++(int);
PtrToTime& operator--();
PtrToTime operator--(int);
};