
- •Міністерство надзвичайних ситуацій України Львівський державний університет безпеки життєдіяльності Юрій грицюк, Тарас рак
- •Навчальний посібник
- •Потреба використання об'єктно-орієнтованого програмування
- •Поняття про об’єктно-орієнтований підхід до розроблення складних програм
- •Основні компоненти об’єктно-орієнтованої мови програмування
- •Поняття про універсальну мову моделювання
- •Базові поняття класу
- •Код програми 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
{
myClass 0bjA(4); cout« ObjA.PutO; getchO; return 0;
}
У цьому коді програми конструктор класу myClass приймає один параметр. Зверніть увагу на те, який оголошено об'єкт ObjA у функції main(). Значення 4, що задається у круглих дужках після імені ObjA, є аргументом, який передається параметру х конструктора myClass(), а параметр х, своєю чергою, використовується для ініціалізації члена а. Саме таким способом ми ініціалізуємо члени класу, як це було показано на початку цього навчального посібника. Проте існує і альтернативний варіант ініціалізації. Наприклад, у процесі виконання такої настанови член класу а також набуде значення 4.
myClass ObjA = 4; // Цей формат ініціалізації перетвориться у формат myClass(4).
Як зазначено у коментарі, цей формат ініціалізації автоматично перетвориться у виклик конструктора класу myClass, а число 4 використано як аргумент. Іншими словами, попередня настанова обробляється компілятором так, як вона була записана:
myClass ObjA(4);
У загальному випадку завжди, якщо у Вас є конструктор, який приймає тільки один аргумент, то для ініціалізації змінних об'єкта можна використовувати будь-який з форматів: або ObjA(x), або ObjA = х. Йдеться про те, що при створенні конструктора класу з одним аргументом Ви опосередковано створите перетворення з типу аргумента в тип цього класу.
Для створення "неконвертованого" конструктора використовується специфікатор explicit.
Якщо програмісту не потрібно, щоб таке неявне перетворення мало місце, то можна запобігти цьому за допомогою специфікатора explicit. Ключове слово explicit застосовується тільки до конструкторів. Конструктор, визначений за допомогою специфікатора explicit, буде задіяний тільки у тому випадку, якщо для ініціалізації членів-даних класу використовується звичайний синтаксис конструктора. Ніяких автоматичних перетворень виконано не буде. Наприклад, оголошуючи конструктор класу myClass з використанням специфікатора explicit, ми, тим самим, відміняємо підтримку автоматичного перетворення типів. У цьому варіанті визначення класу функція myClass() оголошується як explicit-конструктор.
#include <iostream> // Для потокового введення-виведення
using namespace std; // Використання стандартного простору імен
class myClass {// Оголошення класового типу int а; public:
explicit myClass(int х) {а = х;} int PutO {return а;}
};
Тепер буде дозволено до застосування тільки конструктори, які задаються в такому форматі:
myClass 0bjA(110);
Потреба неявного перетворення конструктора. Автоматичне перетворення з типу аргумента конструктора у виклик конструктора саме по собі має цікаві наслідки. Розглянемо, наприклад, такий код програми.
Код програми 11.13. Демонстрація механізму використання неявного перетворення конструктора #include <iostream> // Для потокового введення-виведення
using namespace std; // Використання стандартного простору імен
class myClass { // Оголошення класового типу
int п; public:
myClass(int с) {n = с;} int PutO І return n;}
};
int mainO
{
myClass 0bj(10);
cout« Obj.PutO « endl; // Відображає 10
// Тепер використовуємо неявне перетворення для присвоєння нового значення.
Obj = 1000;
cout« Obj.PutO << endl; // Відображає 1000 getchO; return 0;
}
Зверніть увагу на те, що нове значення присвоюється об'єкту Obj за допомогою такої настанови:
Obj = 1000;
Використання такого формату можливе завдяки опосередкованому перетворенню з типу int в тип myClass, яке створюється конструктором myClass(). Звичайно ж, якби конструктор myClass() було оголошено за допомогою специфікатора explicit, то попередня настанова не могла б виконатися.
Синтаксис механізму ініціалізації членів-даних класу
У прикладах програм, наведених у попередніх розділах, члени-даних набували початкові значення у конструкторах своїх класів. Наприклад, наведений нижче код програми починається з клас myClass, який містить два члени-даних а і Ь. Ці члени ініціалізувалися у конструкторі myClass().
Код програми 11.14. Демонстрація механізму ініціалізації членів-даних з використанням конструкторів класу #include <iostream> // Для потокового введення-виведення
using namespace std; // Використання стандартного простору імен
class myClass { // Оголошення класового типу
int а, Ь; public:
// Ініціалізація а і b у конструкторі myClassO, використовуючи звичайний синтаксис. myClass(int х, int у) {а = х; b = у;} int PutAO {return а;} int PutBO {return b;}
};
int mainO
{
myClass ObjA(7,9), ObjB(5, 2);
cout«"Значення об'єкта ObjA =" « ObjA.PutBO «" і" « ObjA.PutA() « endl; cout«"Значення об'єкта ObjB =" « ObjB.PutBO <<" і" << ObjB.PutA() « endl; getchO; return 0;
}
Внаслідок виконання ця програма відображає на екрані такі результати: Значення змінних об'єкта ObjA дорівнює 9 і 7 Значення змінних об'єкта ObjB дорівнює 2 і 5
Присвоєння початкових значень членам-даних а і b у конструкторі, як це робиться у конструкторі myClass(), - звичайна практика, яка застосовується для багатьох класів. Але цей метод придатний не для всіх випадків. Наприклад, якби члени а і b були задані як const-змінні, тобто так: class myClass {// Оголошення класового типу const int а; // const-член const int b; // const-член,
то їм не можна було б присвоїти значення за допомогою конструктора класу myClass, оскільки const-змінні повинні ініціалізуватися одноразово, після чого їм вже не можна надати інші значення. Такі проблеми виникають при використанні посилальних членів, які повинні ініціалізуватися, і при використанні членів класу, які не мають конструкторів за замовчуванням. Для вирішення проблем такого роду у мові програмування C++ передбачено підтримку альтернативного синтаксису ініціалізації членів-даних класу, який дає змогу присвоювати їм початкові значення при створенні об'єкта класу.
Синтаксис ініціалізації членів-даних класу аналогічний тому, який використовують для виклику конструктора базового класу. Ось як виглядає загальний формат такої ініціалізації:
constructor (перелік_аргументів): член 1 (ініціалізація),
член2(ініціалізація),
II...
nnenuN (ініціалізація)
{
// Тіло конструктора
}
Члени, що підлягають ініціалізації, вказуються після конструктора класу, відокремлюються від імені конструктора і переліку його аргументів двокрапкою. При цьому в одному і тому ж переліку можна змішувати звернення до конструкторів базового класу з ініціалізацією його членів.
Нижче представлена попередня програма, але перероблена так, щоби члени а і b були оголошені з використанням модифікатора const, і набували свої початкові значення через альтернативний синтаксис ініціалізації членів-даних класу.
Код програми 11.15. Демонстрація механізму оголошення членів-даних класу з використанням модифікатора const #include <iostream> // Для потокового введення-виведення
using namespace std; // Використання стандартного простору імен
class myClass {// Оголошення класового типу const int а, b; // const-члени public:
// Ініціалізація членів а і b з використанням альтернативного синтаксису ініціалізації. myClass(int х, int у): а(х), Ь(у) {} int PutAO {return а;} int PutBO {return b;}
};