Объективное программирование

Методическое пособие - Компьютеры, программирование

Другие методички по предмету Компьютеры, программирование

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 Организация РБД в виде таблиц ссылок на объекты

--------------------------------