
- •Міністерство надзвичайних ситуацій України Львівський державний університет безпеки життєдіяльності Юрій грицюк, Тарас рак
- •Навчальний посібник
- •Потреба використання об'єктно-орієнтованого програмування
- •Поняття про об’єктно-орієнтований підхід до розроблення складних програм
- •Основні компоненти об’єктно-орієнтованої мови програмування
- •Поняття про універсальну мову моделювання
- •Базові поняття класу
- •Код програми 2.1. Демонстрація механізму оголошення класу та його застосування
- •Поняття про конструктори і деструктори
- •Особливості реалізації механізму доступу до членів класу
- •Класи і структури - споріднені типи
- •Об'єднання та класи - споріднені типи
- •Поняття про вбудовані функції
- •Inline int myClass::Put() return c;
- •Особливості організації масивів об'єктів
- •Особливості використання покажчиків на об'єкти
- •Поняття про функції-"друзі" класу
- •Код програми 3.1. Демонстрація механізму використання "дружньої" функції для доступу до закритих членів класу
- •Код програми 3.2. Демонстрація механізму використання "дружньої" функції для перевірки статусу кожного об'єкта
- •Void Run(); //Таймер відліку часу
- •Void timerClass::Run()
- •Int mainO
- •Особливості механізму динамічної ініціалізації конструктора
- •Int s; public:
- •Void Run(); //Таймер відліку часу
- •Void timerClass::Run()
- •Int mainO
- •Особливості механізму присвоєння об'єктів
- •Int а, ь; public:
- •Int mainO
- •Особливості механізму передачі об'єктів функціям
- •Void Fun(myClassobj)
- •Int mainO
- •Конструктори, деструктори і передача об'єктів
- •Void Get(myClass obj)
- •Int mainO
- •Потенційні проблеми, які виникають при передачі об'єктів
- •Int *р; public:
- •Void Get(myClass &obj) // Передача об'єкта за посиланням
- •Int mainO
- •Особливості механізму повернення об'єктів функціями
- •Void Set(char*s) {strcpy(str, s);}
- •Void Show() {cout «"Рядок:" « str« endl;}
- •Int mainO
- •Int mainO
- •Механізми створення та використання конструктора копії
- •Використання конструктора копії для ініціалізації одного об'єкта іншим
- •Int mainO
- •Механізм використання конструктора копії для передачі об'єкта функції
- •Int mainO
- •Механізм використання конструктора копії при поверненні функцією об'єкта
- •Int mainO
- •3.7.4. Конструктори копії та їх альтернативи
- •Поняття про ключове слово this
- •Void Fun() {...};
- •Int mainO
- •Механізми перевизначення операторів з використанням функцій-членів класу
- •Int х, у, z; //Тривимірні координати
- •Int mainO
- •Intх,у,z; //Тривимірні координати
- •Void Show(char*s);
- •Int mainO
- •Int х, у, z; //Тривимірні координати
- •Int mainO
- •Особливості реалізації механізму перевизначення операторів
- •Механізми иеревизначення операторів з використанням функцій-не членів класу
- •Використання функцій-"друзів" класу для перевизначення бінарних операторів
- •Void Show(char*s);
- •Int mainO
- •Int mainO
- •Використання функцій-"друзів" класу для перевизначення унарних операторів
- •Int mainO
- •Особливості реалізації оператора присвоєння
- •Int mainO
- •Int mainO
- •Механізми перевизначення оператора індексації елементів масиву "[]"
- •Int mainO
- •Int aMas[size]; public:
- •Int mainO
- •Int aMas[size]; public:
- •Int mainO
- •Механізми перевизначення оператора виклику функцій "()"
- •Int mainO
- •Механізми перевизначення рядкових операторів
- •Конкатенація та присвоєння класу рядків з рядками класу
- •Void Show(char*s) {cout« s « string « endl;}
- •Конкатенація та присвоєння класу рядків з рядками, що закінчуються нульовим символом
- •Void Show(char*s) {cout« s « string « endl;}
- •Void Show(char*s) {cout« s « string « endl;}
- •Int mainO
- •Поняття про успадкування в класах
- •Int kolesa; // Кількість коліс int pasagyr; // Кількість пасажирів public:
- •Int mistkist; // Вантажомісткість у м куб. Public:
- •Int kolesa; // Кількість коліс int pasagyr; // Кількість пасажирів public:
- •Int mainO
- •Використання специфікатора доступу protected для надання членам класу статусу захищеності
- •Int mainO
- •Int mainO
- •Int d; // Захищений public:
- •Int mainO
- •Protected-членом класу derived, що робить його недоступним за його межами. */
- •Void showX() {cout« х « endl;}
- •Void showY() {cout« у « endl;}
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Успадкування віртуальних функцій
- •Void Show() {cout« Суг("Другий похідний клас.") « endl;}
- •Virtual void Show() {cout« Суг("Базовий клас.") « endl;}
- •Void Show() {cout« Суг("Перший похідний клас. ")« endl;}
- •Int mainO
- •Virtual void ShowO {cout« Суг("Базовий клас.") « endl;}
- •Void Show() {cout« Суг("Перший похідний клас. ")« endl;}
- •Int mainO
- •Void Show()
- •Void Show()
- •Int mainO
- •Void Show()
- •Void Show()
- •Int mainO
- •Void swapAb(aType &а, аТуре &b)
- •Int mainO
- •Приклад створення узагальненого класу для організації безпечного масиву
- •Int mainO
- •Використання в узагальнених класах аргументів, що не є узагальненими типами
- •Використання в шаблонних класах аргументів за замовчуванням
- •Int mainO
- •Механізм реалізації безпосередньо заданої спеціалізації класів
- •Int mainO
- •Основні особливості оброблення виняткових ситуацій
- •Системні засоби оброблення винятків
- •Xtest(1);
- •Xtest(2);
- •Перехоплення винятків класового типу
- •Використання декількох catch-наетанов
- •Варіанти оброблення винятків
- •Перехоплення всіх винятків
- •Накладання обмежень на тип винятків, які генеруються функціями
- •Int mainO
- •Xhandler(o); // Спробуйте також передати функції XhandlerO аргументи 1 і 2.
- •Void Xhandler(int test) throw 0
- •Повторне генерування винятку
- •Int mainO
- •Int mainO
- •Механізми перевизначення операторів new і delete
- •Void *р;
- •Void *p;
- •Int mainO
- •Класи потоків
- •Особливості механізмів перевизначення операторів введення-виведення даних
- •Створення перевюначених операторів виведення даних
- •Int mainO
- •Використання функцій-"друзів" класу для перевюначення операторів виведення даних
- •Int х, у, z; //Тривимірні координати (тепер це private-члени) public:
- •Int mainO
- •Створення перевюначених операторів введення даних
- •Istream &operator»(istream &stream, kooClass &obj)
- •Cout«"Введіть координати X, у і z:
- •Stream » obj.X » obj.Y » obj.Z;
- •Istream &operator»(istream &stream, objectType &obj)
- •// Код операторної функції введення даних
- •Class kooClass {// Оголошення класового типу int х, у, z; // Тривимірні координати
- •Istream &operator»(istream &stream, kooClass &obj)
- •Int mainO
- •Void unsetf(fmtflags flags),
- •Void showflags(ios::fmtflags f); // Відображення поточного стану опцій
- •Int mainO
- •Ios::fmtflags f; // Оголошення параметру для поточного стану опцій
- •Int mainO
- •Створення власних маніиуляторних функцій
- •Організація файлового введення-виведення даних
- •Відкриття та закриття файлу
- •Зчитування та запис текстових файлів
- •Ifstream in(argv[1], ios::in | ios::binary); if(!in){
- •In.CloseO; getchO; return 0;
- •Int mainO
- •Зчитування та записування у файл блоків даних
- •Int mainO
- •Ifstream inftest", ios::in | ios::binary); if(!in){
- •Використання функції eof() для виявлення кінця файлу
- •If(!in.Eof()) cout« ch;
- •In.CloseO; getchO; return 0;
- •Int main(int arge, char *argv[])
- •Ifstream f1(argv[1], ios::in | ios::binary); if(!f1) {
- •Ifstream f2(argv[2], ios::in | ios::binary);
- •Int main(int arge, char *argv[])
- •Ifstream in(argv[1], ios::in | ios::binary); if(!in){
- •In.Seekg(atoi(argv[2]), ios::beg); while(in.Get(ch)) cout« ch; getchO; return 0;
- •Int х, у, z; // Тривимірні координати; вони тепер закриті public:
- •Int mainO
- •Virtual void Fun() {}; // Робимо клас Base поліморфним
- •Int mainO
- •Virtual void FunO {cout«"у класі Base"« endl;}
- •Int mainO
- •Virtual void FunO {}
- •Void derivedOnlyO {cout«"Це об'єкт класу Derived"« endl;}
- •Int mainO
- •Void Fun(const int *р)
- •Int mainO
- •Namespace ns { int d;
- •Застосування настанови using
- •Int Comp(const void *а, const void *b);
- •Int mainO
- •Int Comp(const void *a, const void *b)
- •Int mainO
- •Int Fun10 const; // const-функція-член
- •Int PutO const; return c; // Все гаразд
- •Int mainO
- •0Bj.Set(1900); cout « Obj.PutO;
- •Void setJ(int х) const // Наступна функція не відкомпілюється.
- •Int а; public:
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int myClass::*dp; // Покажчик на int-члена класу void (myClass::*fp)(int X); // Покажчик на функцію-члена
- •Int mainO
- •Механізми роботи з векторами
- •Int mainO
- •1 234 5 678 9 10 11 12 13141516 17 1819 Вміст подвоєно:
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Int mainO
- •Символи н
- •Символів представляють голосні звуки.
- •Int mainO
- •Int mainO
- •Int mainO
- •Void getaLine(string& inStr); // Отримання рядка тексту char getaCharO; //Отримання символу
- •Int aptNumber; // Номер кімнати мешканця
- •Void DisplayO; // Виведення переліку мешканців
- •Int aptNo; float rent[12]; public:
- •Void setRent(int, float); // Запис плати за місяць
- •Void insertRent(int, int, float); void DisplayO;
- •Int month, day; string category, payee; float amount; expense() {}
- •Int mainO
- •Void rentRecord::insertRent(int aptNo, int month, float amount)
- •SetPtrsRr.Insert(ptrRow); // Занести рядок вектор
- •If( setPtrsRr.Empty())
- •Else // Інакше
- •Int month, day; string category, payee; float amount;
- •«" 'Є' для запису витрат:";
- •Навчальний посібник
Int mainO
{
map<char, int> h; // Створення порожнього відображення.
// Поміщаємо пари у відображення.
for(int і=0; і<10; і++) {
h.insert(pair<char, int>('A'+i, і));
}
char ch;
cout « "Введіть ключ: "; сіп » ch;
map<char, int>::iteratorp;
// Знаходимо значення за заданим ключем.
р = h.find(ch);
if(p != h.end()) cout « p->second;
else cout « "Такого ключа у відображенні немає" « endl;
getchQ; return 0;
Зверніть увагу на використання шаблонного класу pair для побудови пар "ключ-значення". Типи даних, які задаються раіг-виразом, повинні відповідати типам відображення, в які вставляються ці пари.
Після ініціалізації відображення ключами і значеннями можна виконувати пошук значення за заданим ключем, використовуючи функцію find(). Ця функція повертає ітератор, який вказує на потрібний елемент або на кінець відображення, якщо заданого ключа не було знайдено. Внаслідок виявлення збігу значення, пов'язаного з ключем, можна знайти в члені second парного об'єкта типу pair.
У наведеному вище прикладі пари "ключ-значення" створювалися безпосередньо за допомогою шаблону pair<char, int>. І хоча у цьому немає нічого неправильного, часто простіше використовувати з цією метою функцію make_pair(), яка створює pair-об'єкт на основі типів даних, які використовуються як параметри. Наприклад, цей рядок коду програми також дасть змогу вставити у відображення h пари "ключ-значення" (при використанні попереднього коду програми):
h. insert(make_pair((char)('A'+c), с));
У цьому записі, як бачите, здійснюється операція приведення до типу char, яка необхідна для перевизначення автоматичного перетворення в тип int результату додавання значення і з символом 'А'.
Зберігання у відображенні об'єктів класу
Подібно до всіх інших контейнерів, відображення можна використовувати для зберігання об'єктів, створюваних Вами типів. Наприклад, наведений нижче код програми створює простий словник на основі відображення слів з їх значеннями. Але спочатку вона створює два класи word і meaning. Оскільки відображення підтримує відсортований список ключів, програма також визначає для об'єктів типу word оператора "<". У загальному випадку оператор "<" необхідно визначати для будь-яких класів, які Ви плануєте використовувати як ключі. Деякі компілятори можуть зажадати визначення і інших операторів порівняння.
Код програми 12.12. Демонстрація механізму використання відображення для
#include
<vcl> #include <iostream> #include <conio>
#include <map> #include <cstring> using namespace std;
// Для потокового введення-виведення // Для консольного режиму роботи // Для роботи з асоціативними контейнерами // Для роботи з рядковими типами даних // Використання стандартного простору імен
class word {
char str[20]; public:
wordO {strcpy(str,} word(char*s) {strcpy(str, s);} char*get() {return str;}
};
bool operator<(word ObjA, word ObjB)
{
return strcmp(ObjA.getO, ObjB.getO) < 0;
}
class meaning { char str[80]; public:
meaningO {strcmp(str,} meaning(char*s) {strcpy(str, s);} char*getO {return str;}
};
int mainO
{
map<word, meaning> dictionary;
// Поміщаємо у відображення об'єкти класів word і meaning. dictionary.insert(pair<word, meaning>(
word("fliM"), meaningC'Micqe мешкання.")));
dictionary.insert(pair<word, meaning>(
word("KnaBiaTypa"), теапіпд("Пристрій введення даних.")));
dictionary.insert(pair<word, meaning>(
word("пpoфaмyвaння"), теапіпд("Процес розроблення програми.")));
dictionary.insert(pair<word, meaning>(
wordfSTL"), meaningfStandard Template Library")));
// За заданим словом знаходимо його значення, char str[80];
cout«"Введіть слово:"; сіп » str;
map<word, meaning>::iteratorp; p = dictionary.find(word(str)); if(p != dictionary.endO)
cout«"Визначення:" « p->second.getO;
else
cout«"Такого слова у словнику немає" « endl; getchO; return 0;
}
Один з можливих варіантів виконання цієї програми Введіть слово: дім Визначення: Місце мешкання.
У цьому коді програми кожен елемент відображення є символьним масивом, який містить рядок, який завершується нульовим символом, Нижче у цьому розділі розглядається простіший варіант побудови цієї програми, у якій використано стандартний тип string.
Алгоритми оброблення контейнерних даних
Алгоритми обробляють дані, які містяться у контейнерах. Незважаючи на те, що кожен контейнер забезпечує підтримку власних базових операцій, однак стандартні алгоритми дають змогу виконувати більш розширені або складніші дії. Вони також дають змогу виконувати дії з двома різними типами контейнерів одночасно. Для отримання доступу до алгоритмів бібліотеки STL необхідно приєднати до програми заголовок <algorithm>
У бібліотеці STL визначено багато алгоритмів, які описано в табл. 12.5. Всі ці алгоритми є шаблонними функціями. Це означає, що їх можна застосовувати до контейнера будь-якого типу.
Табл. 12.5. Алгоритми STL
Алгоритм |
Призначення |
1 |
2 |
adjacent_find |
Здійснює пошук суміжних елементів, які збігаються усередині послідовності, і повертає ітератор для першого знайденого збігу |
binary_search |
Здійснює двійковий пошук заданого значення усередині впорядкованої послідовності |
сору |
Копіює послідовність |
copy_backward |
Аналогічний алгоритму copy, за винятком того, що копіювання відбувається у зворотному порядку, тобто спочатку переміщаються елементи, які знаходяться у кінці послідовності |
count |
Повертає кількість елементів із заданим значенням у послідовності |
countjf |
Повертає кількість елементів, які задовольняють заданий предикат |
equal |
Визначає, чи однакові два діапазони |
equal_range |
Повертає діапазон, у який можна вставити елемент, не порушуючи порядок певної послідовності |
fill, fill n |
Заповнюють діапазон заданим значенням |
find |
У заданому діапазоні здійснює пошук заданого значення і повертає ітератор для першого входження знайденого елемента |
find_end |
У заданому діапазоні здійснює пошук заданої послідовності. Повертає ітератор, який відповідає кінцю шуканої послідовності |
find_first_of |
Здійснює пошук першого елемента усередині заданої послідовності, який збігається з будь-яким елементом із заданого діапазону |
findjf |
У заданому діапазоні здійснює пошук елемента, для якого визначений користувачем унарний предикат повертає значення true |
for each |
Застосовує задану функцію до заданого діапазону елементів |
generate, generate_n |
Присвоюють значення, яке повертаються деякою функцією- генератором, елементам із заданого діапазону |
includes |
Встановлює факт внесення всіх елементів однієї заданої послідовності в іншу задану послідовність |
1 |
2 |
inplace_merge |
Об'єднує один заданий діапазон з іншим. Обидва діапазони мають бути відсортовані у порядку зростання. Після виконання алгоритму отримана послідовність сортується у порядку зростання |
iter_swap |
Змінює місцями значення, яке адресуються ітераторами, які передаються як параметри |
lexicographical_compare |
Порівнює одну задану послідовність з іншою в лексикографічному порядку |
lower_bound |
Здійснює пошук першого елемента у заданій послідовності, значення якого не менше від заданого значення |
make heap |
Створює сукупність із заданої послідовності |
max |
Повертає максимальне з двох значень |
max_element |
Повертає ітератор для максимального елемента усередині заданого діапазону |
merge |
Об'єднує дві впорядковані послідовності, поміщаючи результат у третю послідовність |
min |
Повертає мінімальне з двох значень |
min_element |
Повертає ітератор для мінімального елемента усередині заданого діапазону |
mismatch |
Здійснює пошук першого не збігання елементів у двох послідовностях і повертає ітератори для цих двох елементів |
next permutation |
Створює наступну перестановку заданої послідовності |
nth_element |
Упорядковує задану послідовність так, щоби всі елементи, значення яких менші від значення Є, розміщувалися перед цим елементом, а всі елементи, значення яких є більшим від значення Є, розміщувалися після нього |
partial sort |
Сортує заданий діапазон |
partial_sort_copy |
Сортує заданий діапазон, а потім копіює стільки елементів, скільки може поміститися в остаточну послідовність |
partition |
Сортує задану послідовність так, щоб усі елементи, для яких заданий предикат повертає значення true, розміщувалися перед елементами, для яких цей предикат повертає значення false |
pop_heap |
Змінює місцями перший і передостанній елементи заданого діапазону, а потім перебудовує сукупність |
prev permutation |
Створює попередню перестановку послідовності |
push heap |
Поміщає елемент у кінець сукупності |
random shuffie |
Додає випадковий характер заданій послідовності |
remove, remove_if, remove copy, remove copy if |
Видаляють елементи із заданого діапазону |
replace, replace_copy, replace if, replace copy if |
Замінюють задані елементи з діапазону іншими елементами |
reverse, reverse_copy |
Змінює порядок слідування елементів у заданому діапазоні на протилежний |
rotate, rotate_copy |
Здійснює циклічний зсув вліво елементів у заданому діапазоні |
search |
Здійснює пошук однієї послідовності усередині іншої |
search_n |
Усередині певної послідовності здійснює пошук заданої кількості подібних елементів |
set_difference |
Створює послідовність, яка містить різницю двох впорядкованих множин |
1 |
2 |
set_intersection |
Створює послідовність, яка містить перетин двох впорядкованих множин |
set_symmetric_difference |
Створює послідовність, яка містить симетричну різницю двох впорядкованих множин |
set_union |
Створює послідовність, яка містить об'єднання двох впорядкованих множин |
sort |
Сортує заданий діапазон |
sort heap |
Сортує сукупність у заданому діапазоні |
stable_partition |
Упорядковує задану послідовність так, щоб усі елементи, для яких заданий предикат повертає значення true, розміщувалися перед елементами, для яких цей предикат повертає значення false. Таке розбиття є стабільним, що означає збереження відносного порядку послідовності |
stable_sort |
Здійснює стійке (стабільне) сортування заданого діапазону. Це означає, що однакові елементи не переставляються |
swap |
Змінює місцями задані два значення |
swap ranqes |
Здійснює обмін елементів у заданому діапазоні |
transform |
Застосовує функцію до заданого діапазону елементів і зберігає результат у новій послідовності |
unique, unique copy |
Видаляє елементи, які повторюються, із заданого діапазону |
upper_bound |
Знаходить останній елемент у заданій послідовності, який не більший від заданого значення |
Обчислення кількості елементів
Одна з найпопулярнішнх операцій, яку можна виконати для будь-якої послідовності елементів, - це обчислення їх кількості. Для цього можна використовувати один з алгоритмів: count() або count_if(). Загальний формат цих алгоритмів має такий вигляд:
template <class Inlter, class myType>
ptrdiff_t count(lnlter start, Inlter end, const myType &val)\
template <class Inlter, class UnPred>
ptrdiff_t count_if(lnlter start, Inlter end, UnPred p/77);
Алгоритм countO повертає кількість елементів послідовності, які дорівнюють значенню val, межі якої задані параметрами start і end. Алгоритм count_if(), діючи у послідовності, межі якої задані параметрами start і end, повертає кількість елементів, для яких унарний предикат pfn повертає значення true. Тип ptrdiff_t визначається як певний різновид цілочисельного типу.
Механізм використання алгоритмів countO і count_if() продемонстровано у наведеному нижче коді програми.
Код програми 12.13. Демонстрація механізму використання алгоритмів count і count_if
#include <vcl>
#include <iostream> // Для потокового введення-виведення
#include <conio> // Для консольного режиму роботи
#include <vector> // Для роботи з контейнерним класом "Вектор"
#include <algorithm> // Для роботи з алгоритмами бібліотеки STL
#include <cctype> // Для роботи з символьними аргументами
using namespace std; // Використання стандартного простору імен
// Це унарний предикат, який визначає, чи представляє цей символ голосний звук, //абвгдеєжзиіїйклмнопрстуфхцчшщюяь bool isvowel(charch){ ch = tolower(ch);
if(ch=='a' || ch=='e' || ch=='e' || ch=='n'
|| ch=='i' || ch==T || ch=='o' || ch=='y' jj ch=='io' || сіі=='я') return true; return false;
}