С++: Каков размер объекта пустого класса?

Мне было интересно, что может быть размером объекта пустого класса. Это, конечно, не могло быть 0 байтов, так как должно быть возможно ссылаться и указывать на него, как на любой другой объект. Но насколько велик такой объект?

Я использовал эту небольшую программу:

#include <iostream>
using namespace std;

class Empty {};

int main()
{
    Empty e;
    cerr << sizeof(e) << endl;
    return 0;
}

Результат, полученный мной на компиляторах Visual С++ и Cygwin-g++, был 1 байт! Это было немного удивительно для меня, так как я ожидал, что он будет иметь размер машинного слова (32 бита или 4 байта).

Может ли кто-нибудь объяснить почему размер 1 байт? Почему не 4 байта? Это зависит от компилятора или машины? Кроме того, может ли кто-нибудь дать более убедительную причину, почему пустой объект класса не будет иметь размер 0 байтов?

Ответы

Ответ 1

Цитата Часто задаваемые вопросы по стилю и технике Bjarne Stroustrup С++, причина, по которой размер не равен нулю: "Чтобы гарантировать, что адреса двух разных объектов будут разными". И размер может быть равен 1, потому что выравнивание здесь не имеет значения, поскольку на самом деле ничего не видно.

Ответ 2

В стандарте указано, что все наиболее производные объекты имеют sizeof() >= 1:

Если это бит-поле (class.bit), наиболее производный объект должен иметь ненулевой размер и должен занимать один или несколько байтов хранения. Субъекты базового класса могут иметь нулевой размер. ISO/IEC FDIS 14882: 1998 (E) intro.object

Ответ 3

Это действительно деталь реализации. Когда-то давно я думал, что это может быть нулевой байт или тысяча байт, что он не имеет никакого отношения к спецификации языка. Но, посмотрев на стандарт (раздел 5.3.3), sizeof определяется как всегда возвращающий один или более, независимо от того, что.

Размер самого производного класса должен быть больше нуля.

Это требуется, помимо прочего, для обработки массивов объектов и указателей. Если вашим элементам было присвоено нулевое значение, то &(array[0]) будет идентичным &(array[42]), что вызовет всевозможные хаосы для ваших циклов обработки.

Причина, по которой это может быть не машинное слово, состоит в том, что в нем нет элементов, которые на самом деле требуют выравнивания на границе слова (например, целое число). Например, если вы помещаете char x; int y; внутри класса, мой GCC синхронизирует его с восемью байтами (поскольку второй int должен быть выровнен в этой реализации).

Ответ 4

Несмотря на то, что не требуется назначать какую-либо память для пустого класса, но для создания объектов пустых классов компилятор назначает минимальную память, которая может быть назначена, то есть 1 байт. Таким образом, компилятор может различать два объекта одного и того же пустого класса однозначно и сможет присвоить адрес объекта указателю пустого типа класса.

Ответ 5

Существует исключение: массивы длиной 0 строк

#include <iostream>

class CompletlyEmpty {
  char NO_DATA[0];
};

int main(int argc, const char** argv) {
  std::cout << sizeof(CompletlyEmpty) << '\n';
}

Ответ 7

Это может помочь u:-) http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a

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

Причина, по которой это происходит, сводится к правильной реализации стандарт, одна из тех, что говорит стандарт С++, заключается в том, что "нет объекта должен иметь тот же адрес в памяти, что и любая другая переменная".... Что это самый простой способ обеспечить это? Убедитесь, что все типы имеют ненулевой размер. Для этого компилятор добавляет фиктивный байт к структурам и классам, у которых нет данных и нет виртуальных функции, чтобы они имели размер 1, а не размер 0 и то они гарантированно имеют уникальный адрес памяти.

Ответ 8

Назначение 1 байта для пустого класса зависит от компилятора. Компиляторы должны убедиться, что объекты находятся в разных ячейках памяти, и им необходимо выделить ненулевой размер памяти для объекта. Слушайте заметки по этой теме здесь: http://listenvoice.com/listenVoiceNote.aspx?id=27

Несмотря на то, что компиляторы выделяют ненулевой размер пустого класса, они также выполняют оптимизацию, когда новые классы производятся из пустых классов. Слушайте о простой оптимизации базы данных на опросах по программированию на ListenVoice С++.

Ответ 9

причина для класса без элементов данных, но имеющих размер 1 байт, заключается в том, что этот * сильный текст * должен храниться в памяти, чтобы ссылка или указатель могли указывать на объект этого класса

Ответ 10

пустой класс - этот класс не содержит никакого содержимого.

любой класс, который не является пустым, будет представлен его содержимым в памяти.

теперь как пустой класс будет представлен в памяти? поскольку он не имеет никакого содержания, чтобы показать свое существование в памяти, но класс присутствует, обязательно показывать его присутствие в памяти. Чтобы показать пустое присутствие класса в памяти, требуется 1 байт.

Ответ 11

Я думаю, что это так, потому что, поскольку 1 байт является наименьшим блоком памяти, который можно использовать в качестве заполнителя, и он не может дать нулевой размер, так как не удастся создать массив объектов.

и то, что вы сказали "Это было немного удивительно для меня, так как я ожидал, что он будет иметь размер машинного слова (32 бита или 4 байта)". будет истинным для ссылочной переменной (слова macine) типа empty(), а не для самого класса (который является абстрактным типом данных),

Ответ 12

Я думаю, что этот вопрос имеет только теоретический интерес, но на практике это не имеет значения.

Как уже указывалось другими, извлечение из пустого класса не приносит никакого вреда, так как это не будет потреблять дополнительную память для части базового класса.

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

Нижняя строка: если вы обнаруживаете, что пишете пустой класс X, просто ставьте все функции-члены. Вам тогда не нужно создавать объекты X, и производные классы никак не будут затронуты.

Ответ 13

#include<iostream>
using namespace std;


    class Empty { };
    int main()
    {
        Empty* e1 = new Empty;
        Empty* e2 = new Empty;

        if (e1 == e2)
            cout << "Alas same address of two objects" << endl;
        else
            cout << "Okay it Fine to have different addresses" << endl;

        return 0;
    }

Выход: Хорошо, что у него разные адреса.

Возвращаемый размер 1 гарантирует, что два объекта не будут иметь один и тот же адрес.

Ответ 14

Не обязательно, чтобы два разных объекта имели разные адреса. Различные объекты должны иметь разные адреса, поэтому размер пустого класса всегда 1 байт.

Ответ 15

Я думаю, что если размер пустого класса равен нулю, это означает, что он не существует. Чтобы он (класс) существовал, он должен иметь не менее 1 байт, так как этот байт является адресом памяти/ссылки.

Ответ 16

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