
- •Міністерство надзвичайних ситуацій України Львівський державний університет безпеки життєдіяльності Юрій грицюк, Тарас рак
- •Навчальний посібник
- •Потреба використання об'єктно-орієнтованого програмування
- •Поняття про об’єктно-орієнтований підхід до розроблення складних програм
- •Основні компоненти об’єктно-орієнтованої мови програмування
- •Поняття про універсальну мову моделювання
- •Базові поняття класу
- •Код програми 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
{
// Створення покажчика на void-функцію з одним int-параметром, void (*fp1)(int);
/* Створення покажчика на void-функцію з одним int-параметром і одним параметром типу char. */ void (*fp2)(int, char);
fp1 = space; // Отримуємо адресу функції space(int)
fp2 = space; // Отримуємо адресу функції space(int, char)
fp1 (22); // Виводимо 22 пропуски (цей виклик є аналогічним // виклику (*fp1)(22)). cout«"І" « endl;
fp2(30, 'х'); // Виводимо ЗО символів "х" (цей виклик є // аналогічним до виклику (*fp2)(30, 'х'). cout«"І" « endl;
getchO; return 0;
}
Ось як виглядають результати виконання цієї програми:
І
хххххххххххххххххххххххххххххх|
Як зазначено у коментарях до цієї програми, компілятор здатний визначити, адресу якої перевизначеної функції він отримує, на основі того, як оголошено покажчики fp1 і fp2.
Отже, коли адреса перевизначеної функції присвоюється покажчику на функцію, то саме це оголошення покажчика слугує основою для визначення того, адресу якої функції було присвоєно. При цьому оголошення покажчика на функцію повинно відповідати одній (і тільки одній) з перевизначених функцій. Інакше у програму вноситься неоднозначність, яка викличе помилку компілювання.
Поняття про статичні члени-даних класу
Ключове слово static можна застосовувати і до членів-даних класу. Оголошуючи член-даних класу статичним, ми тим самим повідомляємо компілятор про те, що, незалежно від того, скільки об'єктів цього класу буде створено, існує тільки одна копія цього static-члена. Іншими словами, static-член розділяється між всіма об'єктами класу. Всі статичні дані під час першого створення об'єкта ініціалізу- ються нульовими значеннями, якщо перед цим не представлено інших значень ініціалізації.
Під час оголошення статичного члена-даних у класі програміст не повинен його визначати. Необхідно забезпечити його глобальне визначення поза цим класом. Це реалізується шляхом повторного оголошення цієї статичної змінної за допомогою оператора дозволу області видимості, який дає змогу ідентифікувати, до якого класу вона належить. Тільки у цьому випадку для цієї статичної змінної буде виділено пам'ять.
Розглянемо приклад використання static-члена класу. Вивчіть код цієї програми і постарайтеся зрозуміти, як вона працює.
Код програми 11.9. Демонстрація механізму використання статичних
#include
<vcl> #include <iostream> #include <conio> using
namespace std;
// Для потокового введення-виведення // Для консольного режиму роботи // Використання стандартного простору імен
class ShareVar { static int n; public:
void Set(int c) {n = c;} void ShowQ {cout« n «"}
};
int ShareVar::n; // Визначаємо static-член n int mainO {
ShareVar ObjA, ObjB;
ObjA.ShowO; // Виводиться 0 ObjB.ShowO; // Виводиться 0
ObjA.Set(IO); // Встановлюємо static-членэ n дорівнює 10 ObjA.ShowO; Ч Виводиться 10 ObjB.ShowO;//Також виводиться Ю
getchO; return 0;
}
Зверніть увагу на те, що статичний цілочисельний член п оголошений і у класі ShareVar, і його визначено як глобальна змінна. Як було сказано вище, необхід
ність такого подвійного оголошення зумовлена тим, що під час оголошення члена п у класі ShareVar пам'ять для нього не виділяється. Компілятор C++ ініціалізував змінну п значенням 0, оскільки ніякої іншої ініціалізації у програмі немає. Тому внаслідок двох перших викликів функції Show() для об'єктів ObjA і ObjB відображається значення 0. Потім об'єкт ObjA встановлює члену п значення, яке дорівнює 10, після чого об'єкти ObjA і ObjB знову виводять на екран його значення за допомогою функції ShowO- Але оскільки існує тільки одна копія змінної п, що розділяється об'єктами ObjA і ObjB, то значення 10 буде виведено під час виклику функції ShowO Для обох об'єктів.
Нео! хідноапам ятати! Під час оголошення члена класу статичним Ви забезпечуєте створення тільки однієї його копії, яка буде сумісно використовуватися всіма об'єктами цього класу.
Якщо static-змінна є відкритою (тобто public-змінною), до неї можна звертатися безпосередньо через ім'я її класу, без посилання на будь-який конкретний об'єкт1. Розглянемо, наприклад, таку версію класу ShareVar: class ShareVar { public:
static int n;
void Set(int c) { n = c;}; void ShowO {cou*<< n <<" }
};
У даній версії змінна n є public-членом даних класу. Це дає змогу нам звертатися до неї безпосередньо, як це показано в такій настанові:
ShareVar::n = 100;
У цьому записі значення змінної п встановлюється незалежно від об'єкта, а для звернення до неї достатньо використовувати ім'я класу і оператора дозволу області видимості. Більше того, ця настанова є правомірною навіть для створення яких- небудь об'єктів типу ShareVar. Таким чином, отримати або встановити значення static -члена класу можна до того, як будуть створені будь-які об'єкти.
І хоча Ви, можливо, поки що не відчули потреби в static-членах класу, проте, у міру набуття досвіду програмування мовою C++, Вам доведеться наштовхнутися на ситуацію, коли вони виявляться дуже корисними, тобто дадуть змогу уникнути застосування глобальних змінних.
Можна також оголосити статичною і функцію-члена класу, але це непошире- на практика. До статичної функції-члена класу можуть отримати доступ тільки інші static-члени цього класу2. Статична функція-член не має покажчика this. Створення віртуальних статичних функцій-членів класу не дозволяється. Окрім цього, їх не можна оголошувати з модифікаторами const або volatile. Статичну функцію- члена можна викликати для об'єкта її класу або незалежно від будь-якого об'єкта, а для звернення до неї достатньо використовувати ім'я класу і оператор дозволу області видимості.
Застосування до функцій-членів класу модифікаторів const і mutable
Функції-члени класу можуть бути оголошені з використанням модифікатора const. Це означає, що з покажчиком this у цьому випадку необхідно звертатися як з const-покажчиком. Іншими словами, const-функція не може модифікувати об'єкт, для якого вона викликана. Окрім цього, const-об'єкт не може викликати не const- функцію-члена класу. Але const-функцію-члена можуть викликати як const-, так і не const-об'єкти.
Щоб визначити функцію як const-члена класу, використовується формат, який подано у наведеному нижче прикладі: class аТуре { // Оголошення класового типу int some_var; public: