Форум программистов, компьютерный форум CyberForum.ru

Не могу понять виртуальное наследование - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.86
IO8
0 / 0 / 0
Регистрация: 01.10.2013
Сообщений: 3
01.10.2013, 21:49     Не могу понять виртуальное наследование #1
Непонятны несколько моментов. Как строятся таблицы виртуальных классов?

Есть базовый класс, У него два предка. А еще есть третий класс. И в результате получается ромб

C++
1
2
3
4
5
6
7
          C_A
         /   \
        /     \
      C_B1   C_B2
        \     /
         \   /
          C_C



C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// --------------------------------------------------------
// [url]http://devdoc.web-ide.ru/index.php/content/view/virtual_inheritance.htm[/url]
// TBK - Таблица Виртуальных Классов
 
// sizeof = (a) = 4
class C_A
{
private:
    int a;
 
public:
    void foo()  { a=0;  std::cout << "C_A::foo()\n"; }
};
// 4 байта  a
 
// sizeof = (*vtable1 + a + b1) = 4+4+4 = 12
class C_B1 : virtual public C_A
{
private:
    int b1;
};
// TBK:
// 4 байта  0x00000000
// 4 байта  0x00000018 = 24 (почему по этому адресу записано это значение?)
 
// sizeof = (*vtable2 + a + b2) = 4+4+4 = 12
class C_B2 : virtual public C_A
{
private:
    int b2;
};
// TBK:
// 4 байта  0x00000000
// 4 байта  0x00000010
 
// sizeof = (*vtable1+b1) + (*vtable2+b2) + (c) + (a)
// sizeof = (4+4) + (4+4) + (4) + (4) = 8+8+4+4 = 24
class C_C : public C_B1, public C_B2
{
private:
    int c;
};
Почему для класса C_B1 таблица именно такая, Как она вообще создается?
C++
1
2
3
// TBK:
// 4 байта  0x00000000
// 4 байта  0x00000018 = 24 (почему по этому адресу записано это значение?)
Добавлено через 5 минут
И еще вопрос по этой же теме. Почему в этой таблице по нулевому адресу записано 00000000?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.10.2013, 21:49     Не могу понять виртуальное наследование
Посмотрите здесь:

Может ли виртуальное наследование быть одиночным? C++
C++ Виртуальное наследование
C++ Виртуальное наследование (указатель на базовый класс)
Виртуальное наследование C++
C++ Концептуальная задача по ООП (виртуальное наследование в C++)
Виртуальное наследование C++
Для чего нужны виртуальные функции и виртуальное наследование ? C++
C++ Не могу понять, в чем ошибка. Наследование классов

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IO8
0 / 0 / 0
Регистрация: 01.10.2013
Сообщений: 3
01.10.2013, 22:19  [ТС]     Не могу понять виртуальное наследование #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class A
{
    int a;
public:
    void foo(){ a = 0;};
};
 
class B1 : virtual public A
{ 
    int b1;
};
 
class B2 : virtual public A
{
    int b2;
};
class C : public B1, public B2
{
    int c;
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    С c;
    c.foo();
 
    return 0;
}


Теперь вызов c.foo() не вызывает никаких проблем, т.к. компилятор автоматически выполняет все необходимые преобразования для приведения типов. Сейчас в иерархии находится только один подобъект класса A, поэтому конфликта не возникает.

Реализация таблицы виртуальных классов (ТВК) никак не регламентируется и лежит на совести разработчиков компилятора. Я для примера разберу, что делает компилятор MS VC++ 2003 .NET, чтобы вы лучше понимали что происходит.

Итак, будем рассматривать классы из предыдущих примеров. При создании класса C компилятор формирует в памяти следующие структуры:



Таблицы виртуальных классов содержат смещения относительно начала класса для доступа к полям класса А. Так ТВК для B1 содержит смещение 0x18 (24) относительно начала класса B1 для доступа к полям класса A. Обратите внимание, что первый элемент ТВК содержит нулевое смещение. Очевидно, что это смещение для доступа к собственным полям. ТВК для B2 содержит уже другое смещение, т.к. его позиция в пределах всего класса C уже другая. ТВК, как и таблицы виртуальных функций, распределяются статически. Т.е. одна копия таблицы используется всеми классами типа C.




Почему Таблица Виртуальных Классов содержит эти значения? Объясните. А то вообще не разберусь с этой темой
Миниатюры
Не могу понять виртуальное наследование  
IO8
0 / 0 / 0
Регистрация: 01.10.2013
Сообщений: 3
01.10.2013, 22:37  [ТС]     Не могу понять виртуальное наследование #3
Цитата Сообщение от IO8 Посмотреть сообщение
Так ТВК для B1 содержит смещение 0x18 (24) относительно начала класса B1 для доступа к полям класса A.
Допустим. И куда мы попадем по этому смещению? Ведь размер класса B1 меньше 24 байта!

Добавлено через 5 минут
Вот никак до меня не доходит. Как по смещению 0x18(24) мы попадаем в поля класса A?
Yandex
Объявления
01.10.2013, 22:37     Не могу понять виртуальное наследование
Ответ Создать тему
Опции темы

Текущее время: 17:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru