Мне было интересно, каков может быть размер объекта пустого класса . Конечно, это не может быть 0 байтов, так как на него должна быть возможность ссылаться и указывать на него, как на любой другой объект. Но насколько велик такой объект?
Я использовал эту небольшую программу:
#include <iostream>
using namespace std;
class Empty {};
int main()
{
Empty e;
cerr << sizeof(e) << endl;
return 0;
}
Результат, который я получил на компиляторах Visual C ++ и Cygwin-g ++, составлял 1 байт ! Для меня это было немного удивительно, поскольку я ожидал, что он будет размером с машинное слово (32 бита или 4 байта).
Кто-нибудь может объяснить, почему размер 1 байт? Почему не 4 байта? Это тоже зависит от компилятора или машины? Кроме того, может ли кто-нибудь дать более убедительную причину, почему пустой объект класса не будет иметь размер 0 байтов?
Ответы:
Цитируя FAQ Бьярна Страуструпа по стилю и технике C ++ , причина, по которой размер не равен нулю, заключается в том, чтобы «гарантировать, что адреса двух разных объектов будут разными». И размер может быть 1, потому что выравнивание здесь не имеет значения, так как на самом деле не на что смотреть.
источник
new
; когда пространство выделено, другое выделение должно иметь другой адрес. И так далее. В пустом классе не обязательно участвует указатель; могут быть указатели на переменные (или ссылки, или локальные / стековые выделения), но они не нулевого размера и не обязательно являются размером указателя.В стандарте указано, что все производные объекты имеют sizeof ()> = 1:
источник
Это действительно деталь реализации. Когда-то давно я думал, что это может быть ноль или тысяча байтов, что не имеет отношения к спецификации языка. Но, посмотрев на стандарт (раздел 5.3.3),
sizeof
определяется как всегда возвращающий один или больше, независимо от того, что.Это необходимо, помимо прочего, для того, чтобы вы могли обрабатывать массивы объектов и указатели на них. Если бы вашим элементам было разрешено иметь нулевой размер, то они
&(array[0])
были бы идентичны&(array[42])
, что вызовет всевозможные хаос в ваших циклах обработки.Причина, по которой это может быть не машинное слово, заключается в том, что в нем нет элементов, которые фактически требуют его выравнивания по границе слова (например, целому числу). Например, если вы разместите
char x; int y;
внутри класса, мой GCC синхронизирует его на восьми байтах (поскольку второй int должен быть выровнен в этой реализации).источник
Есть исключение: массивы нулевой длины.
источник
c
,&c[M] == &c[N]
для каждогоM
andN
(clang ++ 4.1).Несмотря на то, что не требуется назначать какую-либо память для пустого класса, но для создания объектов из пустых классов компилятор назначает минимальный объем памяти, который может быть назначен, который составляет 1 байт. Таким образом, компилятор может однозначно различать два объекта одного и того же пустого класса и сможет назначить адрес объекта указателю типа пустого класса.
источник
Я думаю, что было бы полезно дать ссылку на ответ, объясняющий это тоже самое. Это примерно
boost::compressed_pair
на Logan Капальдо .источник
Это может помочь вам :-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a
источник
Выделение 1 байта для пустого класса зависит от компилятора. Компиляторам необходимо убедиться, что объекты находятся в разных местах памяти, и им необходимо выделить объекту ненулевой размер памяти. Слушайте заметки по этой теме здесь: http://listenvoice.com/listenVoiceNote.aspx?id=27
Несмотря на то, что компиляторы выделяют ненулевой размер пустому классу, они также выполняют оптимизацию, когда новые классы являются производными от пустых классов. Послушайте об оптимизации пустой базы в вопросах собеседования ListenVoice по программированию на C ++.
источник
причина для класса без членов данных, но имеющего размер 1 байт, заключается в том, что этот * строгий текст * должен храниться в памяти, чтобы ссылка или указатель могли указывать на объект этого класса
источник
пустой класс - этот класс не содержит никакого содержимого.
любой непустой класс будет представлен своим содержимым в памяти.
как теперь пустой класс будет представлен в памяти? поскольку у него нет содержимого, нет способа показать его существование в памяти, но класс присутствует, его присутствие в памяти обязательно показать. Чтобы показать наличие пустого класса в памяти, требуется 1 байт.
источник
Я думаю, это так, потому что 1 байт - это наименьшая единица памяти, которую можно использовать в качестве заполнителя, и он не может дать нулевой размер, так как невозможно создать массив объектов ..
и то, что вы сказали: «Это было немного удивительно для меня, так как я ожидал, что оно будет размером с машинное слово (32 бита или 4 байта)». будет верно для ссылочной переменной (слова macine) типа empty (), а не для размера самого класса (который является абстрактным типом данных),
источник
Думаю, этот вопрос представляет только теоретический интерес, но не имеет значения на практике.
Как уже указывалось другими, наследование от пустого класса не причиняет никакого вреда, так как это не потребует дополнительной памяти для части базового класса.
Более того, если класс пуст (это означает, что он - теоретически - не требует никакой памяти для каждого экземпляра, т. Е. Он не имеет каких-либо нестатических элементов данных или виртуальных функций-членов), тогда все его функции-члены могут также (и должен) быть определен как статический. Таким образом, нет необходимости когда-либо создавать экземпляр этого класса.
Итог: если вы обнаружите, что пишете пустой класс X, просто сделайте все функции-члены статическими. Тогда вам не нужно будет создавать X-объекты, и производные классы никоим образом не будут затронуты.
источник
Вывод: Хорошо иметь разные адреса.
Возвращение размера 1 гарантирует, что два объекта не будут иметь одинаковый адрес.
источник
Ненулевое значение гарантирует, что два разных объекта будут иметь разные адреса. У разных объектов должны быть разные адреса, поэтому размер пустого класса всегда составляет 1 байт.
источник
Я думаю, что если размер пустого класса равен нулю, значит, его не существует. Чтобы он (класс) существовал, он должен иметь как минимум 1 байт, поскольку этот байт является адресом памяти / ссылки.
источник
Это из-за этого указателя, хотя указатель имеет (целое число) 4 байта, но он относится к одной ячейке памяти (одна единица), которая составляет 1 байт.
источник