🗊 Презентация Поліморфізм та віртуальні функції

Нажмите для полного просмотра!
Поліморфізм та віртуальні функції, слайд №1 Поліморфізм та віртуальні функції, слайд №2 Поліморфізм та віртуальні функції, слайд №3 Поліморфізм та віртуальні функції, слайд №4 Поліморфізм та віртуальні функції, слайд №5 Поліморфізм та віртуальні функції, слайд №6 Поліморфізм та віртуальні функції, слайд №7 Поліморфізм та віртуальні функції, слайд №8 Поліморфізм та віртуальні функції, слайд №9 Поліморфізм та віртуальні функції, слайд №10 Поліморфізм та віртуальні функції, слайд №11 Поліморфізм та віртуальні функції, слайд №12 Поліморфізм та віртуальні функції, слайд №13 Поліморфізм та віртуальні функції, слайд №14 Поліморфізм та віртуальні функції, слайд №15 Поліморфізм та віртуальні функції, слайд №16 Поліморфізм та віртуальні функції, слайд №17

Вы можете ознакомиться и скачать презентацию на тему Поліморфізм та віртуальні функції. Доклад-сообщение содержит 17 слайдов. Презентации для любого класса можно скачать бесплатно. Если материал и наш сайт презентаций Mypresentation Вам понравились – поделитесь им с друзьями с помощью социальных кнопок и добавьте в закладки в своем браузере.

Слайды и текст этой презентации


Слайд 1


Поліморфізм та віртуальні функції. Похідні класи мають з базовим класом зв'язки двох видів. Перший з них полягає в тому, що екземпляри похідних...
Описание слайда:
Поліморфізм та віртуальні функції. Похідні класи мають з базовим класом зв'язки двох видів. Перший з них полягає в тому, що екземпляри похідних класів використовують всі відкриті члени базового класу – зокрема методи базового класу. class Base { public: void meth () { cout

Слайд 2


Другий вид зв'язку полягає в тому, що: екземпляр базового класу можна створити як екземпляр похідного; посилання на базовий клас може посилатись на...
Описание слайда:
Другий вид зв'язку полягає в тому, що: екземпляр базового класу можна створити як екземпляр похідного; посилання на базовий клас може посилатись на похідний; вказівник на базовий клас може вказувати на похідний. Всі ці операції виконуються без явного приведення типів і є реалізацією відношення «is-a». int main (void) { Base b; SubBase sb; // екземпляр базового класу створюється як похідний Base bb = SubBase (); // екземпляру базового класу присвоюється похідний b = sb; // посилання на базовий клас посилається на похідний Base & bbb = sb; // вказівник на базовий клас вказує на похідний Base *p = &sb; // sb = b; // таке присвоєння неможливе! return 0; }

Слайд 3


Цілком зрозуміла заборона присвоєнь у зворотному напрямку – адже якщо екземпляр похідного класу створюється як базовий, то виникає проблема із...
Описание слайда:
Цілком зрозуміла заборона присвоєнь у зворотному напрямку – адже якщо екземпляр похідного класу створюється як базовий, то виникає проблема із викликом методів похідного класу, яких немає у базовому: class Base { public: void meth () { cout

Слайд 4


Та обставина, що посилання та вказівники базового класу можуть вказувати на екземпляри похідних класів, приводить до низки цікавих можливостей –...
Описание слайда:
Та обставина, що посилання та вказівники базового класу можуть вказувати на екземпляри похідних класів, приводить до низки цікавих можливостей – зокрема методи, які мають параметрами посилання або вказівник на базовий клас, можуть викликатись із аргументами-екземплярами похідних класів: void fun (Base & b) { b.meth(); } int main (void) { Base b; SubBase sb; fun (b); // так можливо fun (sb); // і так теж можливо return 0; } Але в будь-якому разі, функція fun() викликатиме метод meth() базового класу.

Слайд 5


Проте, можлива ситуація, коли успадковані методи похідних класів повинні поводити себе інакше, ніж методи базового класу. Така поведінка називається...
Описание слайда:
Проте, можлива ситуація, коли успадковані методи похідних класів повинні поводити себе інакше, ніж методи базового класу. Така поведінка називається “поліморфною”. (Поліморфний – такий, що має багато форм). Реалізація поліморфного спадкування здійснюється одним із двох способів. 1. Перекриття методів базового класу у похідному класі : class Base { public: void meth () { cout

Слайд 6


В усіх попередніх прикладах зв'язування екземпляру із конкретним методом (функцією-членом класу) відбувалось на етапі компіляції (тобто ще до початку...
Описание слайда:
В усіх попередніх прикладах зв'язування екземпляру із конкретним методом (функцією-членом класу) відбувалось на етапі компіляції (тобто ще до початку її виконання). Ця процедура, як відомо, називається раннім зв'язуванням. Альтернативний спосіб – пізнє зв'язування (інколи – динамічне зв'язування, в С# - динамічний поліморфізм) дозволяє асоціювати об'єкт із методом саме під час виконання програми. 2. Використання віртуальних методів . Пізнє зв'язування стосується функцій-членів (методів), які називаються віртуальними функціями. Віртуальна функція (virtual) оголошується в базовому класі і може бути перевизначена у похідних класах. Сукупність класів, в яких визначається і перевизначається віртуальна функція, називається поліморфним кластером. У межах цього кластеру об'єкт пов'язується із конкретною віртуальною функцією-членом під час виконання програми. Звичайна функція-член також може бути перевизначена у похідному класі, як у попередньому прикладі. Проте без атрибуту virtual до неї буде застосоване лише раннє зв'язування.

Слайд 7


Приклад. class Base { public: virtual void virt () // віртуальний метод { cout
Описание слайда:
Приклад. class Base { public: virtual void virt () // віртуальний метод { cout

Слайд 8


Тепер, якщо визначити зовнішню функцію fun (Base & b), як у попередньому прикладі, то ми побачимо реалізацію пізнього зв'язування: void fun (Base &...
Описание слайда:
Тепер, якщо визначити зовнішню функцію fun (Base & b), як у попередньому прикладі, то ми побачимо реалізацію пізнього зв'язування: void fun (Base & b) { b.virt(); } int main (void) { Base b; SubBase sb; fun (b); // виклик методу virt()базового класу fun (sb);// виклик методу virt()похідного класу return 0; } Рішення про те, який саме метод virt() базового чи похідного класу має бути викликаний, приймається під час виконання програми – це пізнє звязування.

Слайд 9


Віртуальні методи можуть перевантажуватись, як звичайні функції: class Base { public: virtual void virt () // віртуальний метод { cout
Описание слайда:
Віртуальні методи можуть перевантажуватись, як звичайні функції: class Base { public: virtual void virt () // віртуальний метод { cout

Слайд 10


Слід зазначити, що використання пізнього зв'язування достатньо складний механізм, який вимагає суттєвих витрат пам'яті. Тому віртуальними слід робити...
Описание слайда:
Слід зазначити, що використання пізнього зв'язування достатньо складний механізм, який вимагає суттєвих витрат пам'яті. Тому віртуальними слід робити лише такі функції, які дійсно будуть перевизначатись у похідних класах. Зауваження. Конструктори не можуть бути віртуальними – адже похідний клас не спадкує конструктор базового. А от деструктор може бути віртуальним. Користь віртуального деструктора показує наступний приклад, висновком з якого може бути основне правило: Якщо клас містить хоч одну віртуальну функцію, деструктор класу теж слід зробити віртуальним. Взагалі кажучи, якщо клас передбачає спадкування, його деструктор завбачливо мав би бути визначений віртуальним. Проте йти на такі додаткові витрати варто саме тоді, коли в класі є принаймні одна віртуальна функція. Проаналізуємо наступний приклад.

Слайд 11


Приклад. class Base { public: // раніше визначені члени класу ~Base () // звичайний деструктор {cout
Описание слайда:
Приклад. class Base { public: // раніше визначені члени класу ~Base () // звичайний деструктор {cout

Слайд 12


При виконанні цього прикладу можна побачити, що екземпляр класу, що адресується вказівником p, створюється цілком коректно – спочатку працює...
Описание слайда:
При виконанні цього прикладу можна побачити, що екземпляр класу, що адресується вказівником p, створюється цілком коректно – спочатку працює конструктор базового класу, а потім конструктор похідного. Таким чином, створений через вказівник екземпляр похідного класу SubBase потім приводиться до типу вказівника на базовий клас Base. Але – при знищенні цього екземпляру операцією delete спрацьовує лише деструктор базового класу! Це означає втрати пам’яті (memory leaks), адже не була коректно знищена частина екземпляру, яка відповідає похідному класу. Причина в тому, що об’єкт знищується через вказівник на базовий клас, а базовому класу нічого невідомо про похідний, адже працює раннє зв’язування. Щоб позбутись цього ефекту, конструктор в базовому класі слід визначити як віртуальний. Тоді і знищення екземпляру, адресованого вказівником відбудеться коректно:

Слайд 13


Приклад. class Base { public: // раніше визначені члени класу virtual ~Base () // віртуальний деструктор {cout
Описание слайда:
Приклад. class Base { public: // раніше визначені члени класу virtual ~Base () // віртуальний деструктор {cout

Слайд 14


Повернемось ще раз до перевизначення функцій. Якщо в похідному класі визначається метод, одноіменний з віртуальним методом базового класу, але з...
Описание слайда:
Повернемось ще раз до перевизначення функцій. Якщо в похідному класі визначається метод, одноіменний з віртуальним методом базового класу, але з відмінною сигнатурою, він перекриває віртуальний метод базового класу. Це означає, що в похідних класах віртуальний метод базового класу не доступний. class Base { public: // раніше визначені члени класу virtual virt (); // віртуальний метод }; class SubBase : public Base { public : // раніше визначені члени класу virt (int i); // метод - перекриває віртуальний }; int main (void) { Base b = Base (); SubBase sb = SubBase (); sb.virt (10); // припустимо sb.virt (); //помилка – метод баз. класу недоступний return 0; }

Слайд 15


Отже, віртуальна функція – це функція-член класу, помічена словом virtual, для якої можливе перевизначення у всіх або деяких похідних класах. При...
Описание слайда:
Отже, віртуальна функція – це функція-член класу, помічена словом virtual, для якої можливе перевизначення у всіх або деяких похідних класах. При звертанні до екземпляру похідного класу через вказівник або посилання на базовий клас буде виконана саме перевизначена (заміщена) у похідному класі віртуальна функція.

Слайд 16


Абстрактний базовий клас (ABC – Abstract Base Class). Наразі нам відомі правила простого спадкування та більш складного поліморфного спадкування, яке...
Описание слайда:
Абстрактний базовий клас (ABC – Abstract Base Class). Наразі нам відомі правила простого спадкування та більш складного поліморфного спадкування, яке включає використання віртуальних функцій. Наступний рівень складності – абстрактний базовий клас. Необхідність в ньому виникає, коли необхідно описати об'єкти, що мають східну природу, проте їх важко визначити як базовий та похідний класи. Наприклад, розглядаючи такі об'єкти, як прямокутник та ромб, неможливо встановити між ними відношення «Є» (“is-a”), хоча й очевидно, що вони мають багато спільного: наприклад, поняття площі, повороту на площині. У таких випадках необхідно виділити у об'єктів все спільне і створити клас, який буде базовим для них всіх. Якщо реалізація окремих функцій можлива лише на рівні похідних класів, у базовому їх визначають як чисто віртуальні функції. Екземпляри такого базового класу неможливо створити, сам клас називається абстрактним і використовується лише для створення похідних класів.

Слайд 17


Приклад. class Figure // клас абстрактний – він має чисто віртуальну функцію { protected : double x_cnt, y_cnt; // координати центру фігури public:...
Описание слайда:
Приклад. class Figure // клас абстрактний – він має чисто віртуальну функцію { protected : double x_cnt, y_cnt; // координати центру фігури public: Figure (double x=0, double y=0) : x_cnt (x), y_cnt (y) {} // чисто віртуальна функція: virtual double Square () const = 0; }; class Rectangle : public Figure // похідний клас прямокутник { private : double leng, width; public : Rectangle (double l=0,double w=0,double x=0,double y=0); double Square () const { return leng*width; } }; class Rhombus : public Figure // похідний клас ромб { private : double len, angle; public : Rhombus (double l = 0,double a = 0,double x = 0,double y = 0); double Square () const { return len*len*sin(angle); } };



Похожие презентации
Mypresentation.ru
Загрузить презентацию