Віртуальний метод

Віртуальний метод або віртуальна функція — метод об'єкта в об'єктноорієнтованому програмуванні, різний для базового класу і класу нащадка.

Концепція віртуальної функції розв'язує наступну проблему:

У ООП, якщо клас-нащадок наслідується від базового класу, об'єкт екземпляр класу-нащадка може використовуватись або як екземпляр батьківського класу (бути приведеним до батьківського класу), або як екземпляр класу-нащадка. Якщо у класі-нащадку є функції, що перекривають (мають таку ж сигнатуру) функції із батьківського класу, то поведінка при виклику таких методів (при використанні даного об'єкта як екземпляра батьківського класу) є невизначеною.

Відмінність між віртуальністю і не віртуальністю функцій вирішує цю невизначеність. Якщо функція описана як віртуальна у базовому класі, тоді буде викликана функція із класу нащадка (якщо така існує). Якщо вона не віртуальна, тоді — із батьківського класу.

Реалізація

Техніка виклику віртуальних методів називається ще «динамічним (пізнім) зв'язуванням». Ідеться про те, що ім'я методу, використане в програмі, зв'язується з адресою входу конкретного методу динамічно (під час виконання програми), а не статично (під час компіляції), оскільки в момент компіляції, в загальному випадку, неможливо визначити, яка з чинних реалізацій методу буде викликана[джерело?].

У компільованих мовах програмування динамічне зв'язування виконується зазвичай з використанням таблиці віртуальних методів, яка створюється компілятором для кожного класу, що має хоча б один віртуальний метод. В елементах таблиці знаходяться вказівники на реалізації віртуальних методів, що відповідають даному класу (якщо в класі-нащадку додається новий віртуальний метод, його адреса додається в таблицю, якщо в класі-нащадку створюється нова реалізація віртуального методу — відповідне поле в таблиці заповнюється адресою цієї реалізації). Таким чином, для адреси кожного віртуального методу в дереві спадкоємства є одне, фіксоване зміщення в таблиці віртуальних методів. Кожен об'єкт має технічне поле, яке при створенні об'єкта ініціалізується покажчиком на таблицю віртуальних методів свого класу. Для виклику віртуального методу з об'єкта береться покажчик на відповідну таблицю віртуальних методів, а з неї, за відомим фіксованому зсуву, — покажчик на реалізацію методу, використовуваного для даного класу. При використанні множинного спадкоємства ситуація дещо ускладнюється внаслідок того, що таблиця віртуальних методів стає нелінійною[джерело?].

Див. також