МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах
РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ" ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах Гендерна антидискримінаційна експертиза може зробити нас моральними рабами ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів
Контакти
Тлумачний словник Авто Автоматизація Архітектура Астрономія Аудит Біологія Будівництво Бухгалтерія Винахідництво Виробництво Військова справа Генетика Географія Геологія Господарство Держава Дім Екологія Економетрика Економіка Електроніка Журналістика та ЗМІ Зв'язок Іноземні мови Інформатика Історія Комп'ютери Креслення Кулінарія Культура Лексикологія Література Логіка Маркетинг Математика Машинобудування Медицина Менеджмент Метали і Зварювання Механіка Мистецтво Музика Населення Освіта Охорона безпеки життя Охорона Праці Педагогіка Політика Право Програмування Промисловість Психологія Радіо Регилия Соціологія Спорт Стандартизація Технології Торгівля Туризм Фізика Фізіологія Філософія Фінанси Хімія Юриспунденкция |
|
|||||||
Приклад 2Віртуальні функції Віртуальна функція (virtual function) є членом класу. Вона оголошується всередині базового класу і перевизначається у похідному класі. Для того, щоб функція стала віртуальною, перед оголошенням функції ставиться ключове слово virtual. Якщо клас, що містить віртуальну функцію, успадковується, то в похідному класі віртуальна функція перевизначається. По суті, віртуальна функція реалізує ідею "один інтерфейс, безліч методів", яка лежить в основі поліморфізму. Віртуальна функція всередині базового класу визначає вид інтерфейсу цієї функції. Кожне перевизначення віртуальної функції в похідному класі визначає її реалізацію, пов’язану зі специфікою похідного класу. Таким чином, перевизначення створює конкретний метод. При перевизначенні віртуальної функції в похідному класі, ключове слово virtual не потрібне. Віртуальна функція може викликатися так само, як і будь-яка інша функція-член. Однак найбільш цікавий виклик віртуальної функції через вказівник, завдяки чому підтримується динамічний поліморфізм. Вказівник базового класу можна використовувати в якості вказівника на об’єкт похідного класу. Якщо вказівник базового класу посилається на об’єкт похідного класу, який містить віртуальну функцію і для якого віртуальна функція викликається через цей вказівник, то компілятор визначає, яку версію віртуальної функції викликати, спираючись при цьому на тип об’єкта, на який посилається вказівник. При цьому визначення конкретної версії віртуальної функції має місце не в процесі компіляції, а в процесі виконання програми. Іншими словами, тип об’єкта, на який посилається вказівник, і визначає ту версію віртуальної функції, яка буде виконуватися. Тому, якщо два або більше різних класи є похідними від базового, що містить віртуальну функцію, то, якщо вказівник базового класу посилається на різні об’єкти цих похідних класів, виконуються різні версії віртуальної функції. Цей процес є реалізацією принципу динамічного поліморфізму. Фактично, про клас, що містить віртуальну функцію, говорять як про поліморфний клас (polymorphic class).
//приклад використання віртуальної функції class base { public: int i; base (int x} {i = x;} virtual void func () { cout <<" Виконання функції func () базового класу: "; cout << i <<‘\ n’; } ); class derived1: public base { public: derived1 (int x): base (x) {} void func {) { cout << ”Виконання функції func () класу derived1:"; cout << i * i« “\ n”; } }; class derived2: public base { public: derived2 (int x): base (x) {} void func () { cout << " Виконання функції func () класу derived2: “; cout <<i + i << “\n”; ) }; void main () { base * p; base ob (10); derived1 d_ob1 (10); derived2 d_ob2 (10); p = &ob; p‑> func (}; //функція func () класу base p = &d_ob1; p‑> func (); //функція func () похідного класу derived1 p = & d_ob2; p‑> func (); / функція func () похідного класу derived2 }
Після виконання програми на екрані з’явиться наступне: Виконання функції func () базового класу: 10 Виконання функції func () класу derivedl: 100 Виконання функції func () класу derived2: 20
Перевизначення віртуальної функції усередині похідного класу може здатися схожим на перевантаження функцій. Однак ці два процеси зовсім різні. По-перше, перевантажена функція повинна відрізнятися типом і/або кількістю параметрів, а перевизначена віртуальна функція повинна мати такий самий тип параметрів, кількість параметрів, і такий самий тип значення, що повертається. (Насправді, якщо при перевизначенні віртуальної функції ви змінюєте кількість або тип параметрів, вона просто стає перевантаженою функцією і її віртуальна природа втрачається.) Далі, віртуальна функція повинна бути членом класу. Крім цього, якщо деструктори можуть бути віртуальними, то конструктори ні. Щоб підкреслити різницю між перевантаженими функціями і перевизначеними віртуальними функціями, для опису перевизначення віртуальної функції використовується термін підміна (overriding). У розглянутому прикладі створюється три класи. У класі base визначається віртуальна функція func (). Потім цей клас успадковується двома похідними класами: derived1 і derived2. Кожен з цих класів перевизначає функцію func() по-своєму. Всередині функції main () вказівник базового класу р по черзі посилається на об’єкти типу base, derivedl і derived2. Першим вказівником р присвоюється адреса об’єкту ob (об’єкта типу base). При виконанні функції func() через вказівник р використовується її версія з класу base. Таким вказівником р присвоюється адреса об’єкту d_ob1 і функція func () викликається знову. Оскільки версія викликається віртуальної функції визначається типом об’єкта, на який посилається вказівник, то викликається та версія функції, яка перевизначається в класі derivedl. Нарешті, вказівником р присвоюється адреса об’єкту d_ob2, і знову викликається функція func (). При цьому виконується та версія функції func, яка визначена всередині класу derived2.
Віртуальні функції мають ієрархічний порядок спадкування. Крім того, якщо віртуальна функція не підмінюється в похідному класі, то використовується версія функції, визначена в базовому класі. Читайте також:
|
||||||||
|