Void main(). Результатом програми буде таке виведення:
{
A a;
B b;
do_(a);
do_(b);
}
Результатом програми буде таке виведення:
Функція А::f()
Функція А::g()
Функція А::f()
Функція B::g()
Звертання до do_(A&) з об’єктом В призводить до виклику функцій A::f() і B::g(). Це відбувається тому, що при виклику функції do_(b) посилання В& неявно перетвориться в A&. Компілятор бачить, що A::f() – невіртуальна функція і генерує пряме звертання до A::f(). Виклик функції a.g() у do_(A&) опрацьовується інакше, оскільки компілятор виявляє, що g() у класі А оголошена віртуальною. Це призводить до генерації коду, що включає механізм опрацювання віртуальних функцій. Розміщення об’єктів у пам’яті показано на рисунку 4.4.
Під час виконання код використовує таблицю по вказівці vprt в об’єкті класу В, щоб визначити яку функцію викликати при звертанні до g(), і знаходить B::g(). Поле vptr класу В знаходиться в тій же позиції, що і vptr класу А, так що do_(A&) одержує доступ до коректної функції, незалежно від того, який тип об’єкта передається в do_(A&). Проте зверніть увагу на те, що vptr для об’єкта класу А і vptr для об’єкта класу В посилаються на різні таблиці vtbl.
Змінна | Зсув | |||
a -> A:: | Vptr a | A::vtbl | &A::g |
Змінна | Зсув | |||
a -> A:: b-> B:: | Vptr a b | B::vtbl | &B::g |
Рис. 4.4. Розміщення двох об’єктів в пам’яті
Прикладрозміщення об’єктів в пам’яті:
#include <iostream>
using namespace std;
Дата добавления: 2014-12-26; просмотров: 764;