Размер типа с виртуальным базовым классом

76
01 марта 2022, 22:50

Пусть у нас есть такое наследование:

struct B {};
struct DB : B {       
    int k{};
    //int n{};  
};

(Я специально закоментировал второй член, чтобы рассмотреть DB с одним членом как случай №1, а с двумя членами, как случай №2).

Очевидно, что для DB будет выделено

  • случай №1. 4 байт

  • случай №2. 8 байт

А если базовый класс виртуальный, то 64_битном приложении, где sizeof(int) == 4, получаем:

  • случай №1. 16 байт

  • случай №2. тоже 16 байт

Т.е. выравнивание полей тут уже по 8 байт, а не 4. И, соответственно, для наследника:

struct DDB : DB {      
   int p{};            
};

В случаи с обычным наследованием будет выделено:

  • случай №1. 8 байт

  • случай №2. 12 байт

а в случаи с виртуальным базовым классом sizeof(DDB) == 24(для DDB тоже выравнивание _ 8).

Вопрос: Как это понять _ почему при виртуальном наследовании поля выравниваются по размеру указателья ?

Answer 1

Может быть, просто выравнивается по наибольшему члену? А виртуальный класс первым же членом имеет указатель на vtable? Потому что и без него при указателях подлучаеся то же самое:

В Visual Studio для 64 разрялов

struct B {};
struct DB : B {       8 байт
    int k{};
    int n{};
};
struct EB : B {       16 байт
    int *k{};
    int n{};
};
struct FB : B {       16 байт
    int k{};
    int *n{};
};

Но если сказать #pragma pack(4) они сразу становятся 8 12 и 12 байт.

READ ALSO
Поиск простых чисел в матрице [дубликат]

Поиск простых чисел в матрице [дубликат]

Начал изучение C++Нашел такую задачу: поиск простых чисел в матрице

91
Многомерное нормальное распределение

Многомерное нормальное распределение

В стандартной библиотеке есть инструменты для генерации значений из одномерного нормального распределения (std::normal_distribution)Есть ли подобное...

72
Как сделать выборку из двух таблиц MySQL?

Как сделать выборку из двух таблиц MySQL?

Ситуация таковаУ меня в bd есть две таблицы

76
Как передать ArrayList в качестве аргумента

Как передать ArrayList в качестве аргумента

Имеется первый класс One с конструктором, принимающим в качестве аргумента ArrayList типа String, :

216