Почему размер класса в c ++ зависит от публичного / частного статуса членов данных?

23

Из того, что я знаю, размер класса в C ++ зависит от следующих факторов:

  1. Размер всех нестатических элементов данных.
  2. Порядок данных членов.
  3. Если заполнение байтов включено или нет.
  4. Размер его непосредственного базового класса.
  5. Существование виртуальных функций.
  6. Режим наследования (виртуальное наследование).

Теперь я создал 2 класса, как показано ниже -

class A{
    int a;
    short s;
    int b;
    char d;
};// kept a char at last on purpose to leave a "hole"

class B : public A{
    char c;  
};

Теперь о проверке размеров А и БИ см.

  • размер А: 16
  • размер B: 16

я предполагаю, что символ c в классе B размещен в "дыре" слева в классе A.

Но что меня смутило, так это сценарий, приведенный ниже.

class A{
    public:
    int a;
    short d;
    int b;
    char s;
};

class B : public A{
    public:
    char c;
};

Теперь размер становится

  • размер А: 16
  • размер B: 20

Я не могу понять причину этой разницы.

j.doe
источник
1
Почему размер класса в c ++ зависит от публичного / частного статуса членов данных? - Это не так. Это детали реализации, зависящие от компилятора.
PaulMcKenzie
1
Так какой компилятор вы используете?
Ромэн
2
@PaulMcKenzie На самом деле это так. Стандартные мандаты для членов с одинаковым доступом группируются так, что меняются, что изменит стратегию заполнения компилятора.
Натан Оливер
@ NathanOliver-ReinstateMonica, я этого не знал. У вас есть какая-нибудь ссылка на соответствующий раздел?
Р Саху
@RSahu Ищите его, чтобы вставить мой ответ прямо сейчас.
Натан Оливер

Ответы:

8

Itanium ABI использует определение POD в C ++ 03 для определения классов, которые являются «POD для макета». Наличие закрытых членов данных лишает класс возможности быть агрегатом и, следовательно, POD в C ++ 03:

POD-структура не представляет собой совокупность класс , который не имеет не-статические элементы данных типа не-POD-структуры, не-POD-объединения (или массив таких видов) или в качестве ссылки, и не имеет никакого определенного пользователем оператор присваивания копирования и нет пользовательский деструктор.

Наличие класса POD отключает повторное использование хвостового отступа :

Dsize, nvsize и nvalign этих типов определяются как их обычный размер и выравнивание. Эти свойства имеют значение только для непустых типов классов, которые используются в качестве базовых классов. Мы игнорируем хвостовое заполнение для POD, потому что ранняя версия стандарта не позволяла нам использовать его для чего-либо еще, а также потому, что иногда это позволяет быстрее копировать тип.

Таким образом, в вашем первом примере Aэто не POD для целей компоновки, и его хвостовой отступ может использоваться B::c, но во втором примере это POD, и его хвостовой отступ не может быть использован повторно.

TC
источник