Конструктори і таблиця віртуальних методів
Відлагодження програм з використанням віртуальних методів
Розширюваність об’єктів
Переваги і недоліки віртуальних методів
Конструктори і таблиця віртуальних методів
Кожний екземпляр (змінна) типу «об’єкт», що містить віртуальні методи, повинен ініціалізуватися окремим викликом конструктора. Якщо змінна А ініціалізована викликом конструктора, а змінна В того ж типу не ініціалізована, то присвоювання В:=А не ініціалізує змінну В і при виклику її віртуальних методів програма може зависнути.
Щоб зрозуміти, що робить конструктор, розберемося в механізмі реалізації віртуальних методів. Кожен об’єктний тип (саме тип, а не екземпляр) має «таблицю віртуальних методів» (VMT), яка містить розмір типу об’єкту і адреси кодів процедур чи функцій, що реалізують кожен з його віртуальних методів. При виклику віртуального методу яким-небудь екземпляром розміщення коду реалізації цього методу визначається за таблицею VMT для типу цього екземпляра. Конструктор встановлює зв’язок між екземпляром, який викликає цей конструктор, і таблицею віртуальних методів даного об’єктного типу. Якщо ж конструктор не буде викликаний до звертання до віртуального методу, то перед комп’ютером постане питання, де шукати цей метод. Це і призведе до тупикової ситуації.
Важливо пам’ятати, що таблиця віртуальних методів – одна для кожного типу, а не в кожної змінної типу «об’єкт». Змінна лише підтримує зв’язок з таблицею свого типу, і цей зв’язок встановлюється конструктором. В об’єкті може бути визначено кілька конструкторів. Самі конструктори можуть бути лише статичними, хоча всередині конструктора можуть викликатися і віртуальні методи.
При передачі в процедуру чи функцію поліморфного об’єкту, що має віртуальні методи, адреси цих методів передаються через таблицю VMT, що відповідає цьому об’єкту. Це гарантує, що спрацюють саме ті методи, які малися на увазі при оголошенні тапу об’єкта. Крім того, якщо об’єкт Z успадковує від об’єкту Y віртуальний метод, що викликає інші методи, то ці останні виклики будуть відноситися до методів об’єкту Z, а не Y. У випадку статичних методів все було б навпаки (виклики «не повернулись» би в Y).