Объективное программирование
Методическое пособие - Компьютеры, программирование
Другие методички по предмету Компьютеры, программирование
this = (char*)this + db // Адрес объекта класса b в нем
b::f(this); // Вызов функции в классе b со своим
// объектом
Рассмотрим особенности механизма виртуальных функций при
множественном наследовании. Во-первых, на каждый базовый класс в
производном классе создается своя таблица виртуальных функций (в
нашем случае - для "a" в "d", для "b" в "d" и для "c" в "d").
Во-вторых, если функция базового класса переопределена в производном, то при вызове виртуальной функции требуется преобразовать
ссылку на объект базового класса в ссылку на объект производного,
то есть для второго и т.д. базовых классов вычесть из this соответствующее смещение. Для этого транслятор включает соответствующий код, корректирующий значение this в виде "заплаты", передающей управление командой перехода к переопределяемой функции.
class a
{
public: virtual void f();
virtual void g();
};
class b
{
public: virtual void h();
virtual void t();
};
class c : public a, public b
{ // f(),t() наследуются
public: void g(); // g() переопределяется
void h(); // h() переопределяется
}
a A1;
b B1;
c C1;
pa = &A1;
pb = &B1;
pa->f(); // Вызов a::f()
pb->h(); // Вызов b::h()
pa = &C1;
pb = &C1;
pa->f(); // Вызов a::f()
pa->g(); // Вызов c::g()
pb->h(); // Вызов c::h()
pb->t(); // Вызов b::t()
Таблицы виртуальных функций для данного примера имеют вид:
A1
-a---- Таблица ВФ для "a"
------------>--------
+-----+ a::f()
L------ +-------+
a::g()
L------- B1
-b---- Таблица ВФ для "b"
------------>--------
+-----+ b::h()
L------ +-------+
b::t()
L------- C1
T --c----- Таблица ВФ для "a" в "c"
--a--- --------
db ----------->a::f()
L------ +-------+
+ --b--- c::g()
------- L------- L------ Таблица ВФ для "b" в "c"
L--->-------- "Заплата" для c::h()
L-------- xxx()----->--xxx()----------------
+-------+ this=(char*)this - db
b::t() goto c::h
L-------- L----------------------
Другим вариантом решения проблемы является хранение необходимых смещений в самих таблицах виртуальных функций.
7.4. Виртуальные базовые классы
------------------------------
В процессе иерархического определения производных классов
может получиться, что в объект производного класса войдут
несколько объектов базового класса, например
class base {}
class a : public base {}
class b : public base {}
class c : a, b {}
В классе "c" присутствуют два объекта класса base. Для исключения такого дублирования объект базового класса должен быть
объявлен виртуальным
class a : virtual public base {}
class b : virtual public base {}
class c : public a, public b {}
a A1;
b B1;
c C1;
Объект обыкновенного базового класса располагается, как правило, в начале объекта производного класса и имеет фиксированное
смещение. Если же базовый класс является виртуальным, то требуется его динамическое размещение. Тогда в объекте производного
класса на соответствующем месте размещается не объект базового
класса, а ссылка на него, которая устанавливается конструктором.
Для вышеприведенного примера имеем
A1 B1 C1
--a------ --b----- --c---------------
------ ------ --a-------
+--------+ +-------+ -------
+---------+
-base--<---- -base-<----
L------- L------ L----------
L--------- L-------- --b-------
------
+---------+
L----------
-base---<---
L--------<----
L-----------------
Таблицы виртуальных функций располагаются в каждом базовом
классе обычным образом.
Лекция 8. Пример использования виртуальных функций
-------------------------------------------------
Реляционная база данных (РБД) представляет собой таблицу,
состоящую из произвольного количества строк и столбцов. В качестве элементов, хранящихся в клетке такой таблицы могут быть целые,
вещественные числа, строки постоянной и переменной длины, значения даты и времени. Все типы элементов в одном столбце должны
совпадать. Количество строк и столбцов, названия столбцов и типы
элементов в них заранее не известны и определяются динамически,
то есть в процессе работы программы.
В нашем примере рассмотрим РБД, целиком размещенную в памяти.
8.1 Организация РБД в виде таблиц ссылок на объекты
--------------------------------