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

Из того, что я знаю, размер класса в 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;  
};

Теперь о проверке размера A и BI см.

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

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

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

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

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

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

  • размером A: 16
  • размеромиз B: 20 ​​

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

Ответы [ 2 ]

16 голосов
/ 20 ноября 2019

Это связано с тем, что стандарт требует, чтобы элементы с одинаковым контролем доступа были сгруппированы в памяти. Эта группировка решает, как объект будет дополнен, поэтому изменение его может / изменит размер объекта. Примечание для этого можно найти в [class.mem] / 19

[Примечание: нестатические члены-данные класса (не объединения) с одинаковым доступомcontrol и ненулевой размер ([intro.object]) распределяются так, чтобы более поздние члены имели более высокие адреса в объекте класса. Порядок распределения нестатических элементов данных с различным контролем доступа не определен. Требования выравнивания реализации могут привести к тому, что два смежных элемента не будут выделяться сразу после друг друга;то же самое касается требований к пространству для управления виртуальными функциями ([class.virtual]) и виртуальными базовыми классами ([class.mi]). - конец примечания]

7 голосов
/ 21 ноября 2019

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

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

Существокласс POD запрещает повторное использование хвостового отступа :

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...