Derived
необходимо каким-то образом узнать, где подобъект Base
. При виртуальном наследовании относительное местоположение базового класса не фиксируется относительно местоположения производного класса: оно может быть расположено в любом месте полного объекта.
Рассмотрим более типичный пример, связанный с наследованием алмазов.
struct A
{
int a;
};
struct B1 : virtual A
{
int b1;
};
struct B2 : virtual A
{
int b2;
};
struct C : B1, B2
{
int c;
};
Здесь, как и B1
B2
получить практически из A
, поэтому в C
, есть ровно один A
подобъектов. Как B1
, так и B2
необходимо знать, как найти такой объект A
(чтобы они могли получить доступ к переменной-члену a
или другим членам A
, если бы мы их определяли).
В этом случае используется таблица vtable: оба B1
и B2
будут иметь таблицу vtable, которая содержит смещение подобъекта A
.
Чтобы продемонстрировать, что компилятор может сделать для реализации приведенного выше примера алмаза наследования, рассмотрят следующие макеты классов и виртуальные таблицы, сгенерированные Visual C++ 11 Developer Preview.
class A size(4):
+---
0 | a
+---
class B1 size(12):
+---
0 | {vbptr}
4 | b1
+---
+--- (virtual base A)
8 | a
+---
class B2 size(12):
+---
0 | {vbptr}
4 | b2
+---
+--- (virtual base A)
8 | a
+---
class C size(24):
+---
| +--- (base class B1)
0 | | {vbptr}
4 | | b1
| +---
| +--- (base class B2)
8 | | {vbptr}
12 | | b2
| +---
16 | c
+---
+--- (virtual base A)
20 | a
+---
и следующие виртуальные таблицы:
B1::[email protected]:
0 | 0
1 | 8 (B1d(B1+0)A)
B2::[email protected]:
0 | 0
1 | 8 (B2d(B2+0)A)
C::[email protected]@:
0 | 0
1 | 20 (Cd(B1+0)A)
C::[email protected]@:
0 | 0
1 | 12 (Cd(B2+0)A)
Обратите внимание, что смещения относительно адреса виртуальных таблиц, и обратите внимание, что для двух виртуальных таблиц, генерируемых для B1
и B2
подобъектов C
, в смещения разные.
(Также отметим, что это полностью деталь реализации -. Другие составители могут реализовать виртуальные функции и базы по-другому Этот пример демонстрирует один из способов, что они реализуются, и они очень часто реализованы таким образом.)
См. [Может существовать пустая виртуальная таблица?] (Http://stackoverflow.com/questions/7847951/can-an-empty-virtual-table-exist) – Lion