Верона (Італія). Арена, І ст. Якби будівельники будували будинки так, як програмісти складають програми, досить було б залетіти одному дятлу, щоб зруйнувати цивілізацію Постулат Вейнберга Артур Блох. Закон Мерфі
2 Бублик Володимир Васильович Об'єктно-орієнтоване програмування Оглядова лекція для бакалаврів –
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Програма державного іспиту 1.Особливості передачі параметрів та повернення значення функції. Указники і відсилки (pointers and references). 2.Створення і ініціалізація обєктів, довизначення конструкторів, замовчуваний конструктор, обмеження прав доступу до конструктора. 3.Поверхневе і глибоке копіювання обєктів, ініціалізація і присвоєння, копіювальний конструктор. 4.Довизначення (overloading) арифметичних операцій, оператора присвоєння, оператора індексування. 5.Узагальнені функції (function template). 6.Параметризовані класи (class template). 7.Відкрите, закрите і захищене успадкування. 8.Успадкування із спільного базового класу. Домішки (mix-in). 9.Статичне і динамічне звязування: поліморфізм, віртуальні функції 10.Успадкування інтерфейсу і успадкування реалізації. Абстрактні класи.
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Особливості передачі параметрів 1.const T 2.T 3.T& 4.const T& Копіювання, незмінний формальний параметр, немає впливу на фактичний параметр Копіювання, змінний формальний параметр, немає впливу на фактичний параметр Відсилка без копіювання, повний доступ до фактичного параметру (C++) Стала відсилка без копіювання, фактичний параметр незмінний (C++)
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Порівняння типів параметрів Найнадійніший параметр-результат T& Параметри-значення Точка зору користувача: параметри T, const T і const T& не відрізняються з точки зору використання Точка зору розробника: const T надійніший, бо не створює непорозумінь; const T& найефективніший, оскільки не вимагає витрат на копіювання
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Параметри-указники 5.T* 6.const T* 7.T* const 8.const T*const Повний але непрямий доступ до фактичного параметру; передача масивів (T[]) (в стилі чистого С) Маловживаний тип параметру; доступ лише для читання: сталий фактичний параметр (vs const T&) Незмінний формальний параметр- указник, немає впливу на фактичний параметр-адресу (this в C++) Незмінний указник на сталий фактичний параметр В усіх випадках 5-8 сам указник передається значенням
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Головна проблема параметра-указника Як відрізнити масив від скалярного значення? Вихід: жорстка дисципліна програмування, додатковий параметр типу size_t з відповідним коментарем void f (double * px, size_t size_of_px);
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Результат функції Результати значення 1.T f(…); 2.const T f(…); Результати відсилки 3.T& f(…); 4.const T& f(…); Результати указники 5.T* f(…):
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Створення і ініціалізація обєктів class T { T(T1,…,Tn); ~T(); //конструктор копіювання //створює новий об'єкт, ідентичний //переданому параметром T(const T&); //Можливий варіант: T(T&); //але не Т(Т) };
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Автоматичний виклик конструктора і деструктора int main() { //Визначення об'єктів приводить //до виклику конструкторів. //Ось він: WrappedVector w1, w2(n); …………………………………………… //Життя об'єктів завжди закінчується //автоматичним викликом їх деструкторів //ост тут: return 0; }
© Бублик В.В. ООП. Оглядова лекція для бакалаврів new: конструктор; delete: деструктор int main() { WrappedVector *pw; //Створення об'єкту: //неявний виклик конструктора pw = new WrappedVector; ………………………………………………… //Видалення об'єкту: //неявний виклик деструктора delete pw; return 0; }
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Конструктор і деструктор за замовчуванням Так! Компілятор генерує порожні конструктор і деструктор для кожної структури, яка не має власних //Конструктор за замовчуванням PreWrappedVector:: PreWrappedVector(){ }; //Деструктор за замовчуванням PreWrappedVector:: ~PreWrappedVector(){ }; //Краще б їх не було, але так досягається //сумісність С і С++
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Копіювання обєктів Копіювальне присвоєння Конструктор копіювання Конструктор копіювання викликається кожного разу, коли параметр або результат передаються значеннями Передаючи параметр і одержуючи результат, усвідомлюйте, з чим маєте справу: з оригіналом чи копією
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Сигнатури присвоєнь Якій з сигнатур віддати перевагу? 1.void operator=( T&);//Як бути з x=y=z; 2.T operator=( T&);//копіювати результат? 3.T& operator=( T );//копіювати параметр? 4.T operator=( T );//див 2 і 3 разом 5.T& operator=( T&);//краще T& operator=(const T&);
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Порівняння Конструктор копіювання створює новий об'єкт Присвоєння звичайно замінює існуючий об'єкт іншим об'єктом (навіть якщо не доводиться видаляти попередні значення) Присвоєння не можна визначити поза класом Присвоєння в класі T має тип T& (чому?) Присвоєння повертає *this, конструктори не повертають нічого (чому?)
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Довизначення (overloading) операторів Довизначенню підлягають операції, хоча б один аргумент яких належить програмованому типу: класу, структурі або переліку Довизначення можливе як у формі члена класу (методу), так і позакласної функції (утиліти)
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Статичний поліморфізм const Complex i (0, 1), z (1, 1); double x (2), y(3); cout << (x +5) + (z+i) + y<<endl; Complex operator+ (const Complex &, const Complex &); Complex operator+ (double, const Complex &); Complex operator+ (const Complex &, double); ostream& operator<<(ostream &os, const Complex &);
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Узагальнені функції (function template) Myswap.h template void myswap (T &x, T &y) { T z = x; x = y; y = z; return; } Чому не Myswap.сpp?
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Параметризовані класи (class template)
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Масив template class Array { public: explicit Array (size_t); ~Array(); //Модифікатор елементу масива Elem& operator[] (size_t index); //Селектор елементу масива const Elem& operator[] (size_t index) const; //Розмір масива (селектор) size_t size() const;
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Масив (продовження) private: size_t _size; Elem * _pElem; //Операції і функції не визначені для масивів bool operator== (const Array&) const; Array(const Array&); Array& operator= (const Array&); }; template ostream& operator &);
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Відкрите, закрите і захищене успадкування Успадкування лише реалізації private: відкрита і захищена частини базового класу може використовуватися в похідному класі protected: транзитивне (захищене) відкрита і захищена частини базового класу може використовуватися в усіх похідних класах Успадкування реалізації і поведінки public: відкрита частина базового класу стає одночасно відкритою частиною похідного класу
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Формула (відкритого) успадкування Студент теж людина Підоб'єкт успадковує всі властивості (атрибути) і поведінку (відкриті методи) базового об'єкту Підоб'єкт може мати власні додаткові властивості і поведінку Підоб'єкт не має доступу до закритої частини базового об'єкту
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Відкрите (повне) успадкування. Діаграма композиція успадкування Стек з підгляданням не одержав доступу до operator[], який мав стек
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Закрите успадкування (реалізації). Діаграма Підклас має доступ до відкритої і захищеної частини базового класу, але не передає цих прав своїм підкласам Стек все ще мусить містити чужу операцію
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Транзитивне (захищене) успадкування Підклас передає своїм підкласам доступ до відкритої і захищеної частини базового класу так, як ніби вони складали його захищену частину operator[] класу Array одержав статус захищеного оператора класу StackDerivedFromArray
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Порівняння агрегації і успадкування Агрегація: Агрегат користується об'єктом виключно сам Успадкування: Закрите: похідний об'єкт користується базовим об'єктом виключно сам Захищене: похідний об'єкт користується базовим об'єктом сам і передає ці права своїм похідним об'єктам Відкрите: похідний об'єкт користується базовим об'єктом сам і передає ці права своїм похідним об'єктам і клієнтам
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Успадкування із спільного базового класу. class Rectangle: public Parallelogram; class Rhombus: public Parallelogram;
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Mix-in: кратне успадкування class Cat: public Predator, public Pet
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Спільний базовий клас: запит
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Спільний базовий клас: результат
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Віртуальне успадкування Відмінимо виклик конструктора в базових класах змішування Конструктор прямокутника (ромба) викличе конструктор паралелограма лише за умови, що його раніше не викликав конструктор квадрату class Rectangle : virtual public Parallelogram; class Rhombus : virtual public Parallelogram; class Square : public Rectangle, public Rhombus;
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Віртуальне успадкування: вихід
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Статичне і динамічне звязування Об'єкт може належати багатьом типам Квадрат одночасно є прямокутником, ромбом і паралелограмом Прямокутник і ромб одночасно є паралелограмами Ім'я паралелограма здатне приймати значення довільного допустимого типу Параметр Parallelogram & par може прийняти паралелограм, прямокутник, ромб або квадрат Указник Parallelogram * ppar може показувати на кожен з них, наприклад, Parallelogram * ppar = new Squre(10);
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Віртуальні функції Об'єкти володіють даними-членами класу і розділяють функції-члени класу Прямий виклик класної функції (поки що) Triangle((0,0), (0,1), (1,0)).sideA(); Непрямий виклик віртуальної функції перевірити яке саме значення має par взяти функцію (з таблиці віртуальних функцій vtab) Непрямий виклик поширюється лише на спеціально позначені функції
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Забутливе присвоєння Поліморфізм здатен проявитися лише при застосуванні указника базового класу або передачі базового класу відсилкою (в тому числі сталою) Присвоєння об'єкту похідного класу на місце, призначене для базового об'єкту, призведе до забування додаткових властивостей похідного типу і його зведення до базового Parallelogram par = Rectangle(10, 20);
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Успадкування інтерфейсу Можливість динамічно використовувати для роботи з похідними класами інтерфейс (неіснуючого) абстрактного базового класу class Stack { public: virtual~Stack(){}; virtual const Elem& top() const =0; virtual void pop()=0; virtual void push(const Elem& value)=0; };
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Абстрактний клас Відсутність реалізації класної функції позначається нулем Абстрактним називається клас, у якого відсутня реалізація хоча б однієї функції Використовуються для позначення спільного інтерфейсу класів, що допускають різні реалізації Об'єкт абстрактного класу створити не можна (чому?)
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Діаграма реалізацій інтерфейсу
© Бублик В.В. ООП. Оглядова лекція для бакалаврів Enjoy your exam! Košice, Slovakia