2010-03-02 2 views
55

Можно создать дубликат:
C++: What is the size of an object of an empty class?Почему размер пустого класса в C++ не равен нулю?

Почему следующий выходной 1?

#include <iostream> 

class Test 
{ 
}; 

int main() 
{ 
    std::cout << sizeof(Test); 
    return 0; 
} 
+4

Существует фиктивный элемент-заполнитель, размер которого составляет один байт. Поскольку для массива Test [10] каждый объект должен иметь уникальный адрес. – legends2k

+4

Интересной оптимизацией является «Пустая базовая оптимизация», а это означает, что если вы наследуете от пустого базового класса (без атрибута, без виртуальных методов), то размер вашего класса не будет расти. Существует ряд (других) условий, но это объясняет, почему частное наследство от предикатов в некоторых ситуациях. –

+0

[аналогичный вопрос 1] (http://stackoverflow.com/questions/1626446) и [аналогичный вопрос 2] (http://stackoverflow.com/questions/621616/). – Lazer

ответ

86

Стандарт не допускает объекты (и классы таковых) размером 0, так что бы сделать возможным для двух различных объектов, чтобы иметь один и тот же адрес памяти. Поэтому даже пустые классы должны иметь размер (по крайней мере) 1.

+2

Hm ... но не должен ли компоновщик быть в состоянии позаботиться об этом независимо от того, что возвращает sizeof()? Разве это не похоже на побочный эффект? Я понимаю, что вы говорите, но разве не вполне возможно вернуть 0 для sizeof (Test). Но если стандарт говорит так, это так. На самом деле хорошая вещь для того, чтобы быть явным, а не преднамеренно неопределенным в отношении предмета. –

+12

@Amigable, так что бы «Test a [10];' иметь размер? И 'sizeof a/sizeof * a' будет делить на 0. И' for (Test * i = a; i! = A + 10; i ++) f (i); 'также не сработает. Я считаю, что это вызовет массу проблем, так как вам нужно много особых случаев в компиляторах * и * в коде пользователя. –

+0

@Johannes, так верно. Я об этом не думал. –

27

Для обеспечения того, чтобы адреса двух разных объектов были разными. По этой же причине «новый» всегда возвращает указатели на отдельные объекты.

См. Stroustrup для получения полного ответа.

+1

Перейти к прямой ссылке на страницу –

20

Стандарт C++ гарантирует, что размер любого класса не менее одного. В стандарте C++ указано, что ни один объект не должен иметь тот же адрес памяти, что и другой объект. Для этого есть несколько веских причин.

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

  2. Чтобы избежать некоторых делений на ноль. Например, арифметика указателей (многие из которых выполняются автоматически компилятором) включает деление на sizeof(T).

Обратите внимание, однако, что это не означает, что пустой базовый класс добавит 1 к размеру производного класса:

struct Empty { }; 

struct Optimized : public Empty { 
    char c; 
}; 

// sizeof(Optimized) == 1 with g++ 4.0.1 

Bjarne Stroustrup talks about this тоже.

+2

Что такое арифметика указателя включает _dividing_ by 'sizeof (T)'? Я не могу придумать ни одного примера. Plase добавьте хотя бы один пример. – MSalters

+4

@MSalters: итерация по массивам элементов типа T. – wilhelmtell

+1

@MSalters: вычитание двух указателей возвращает количество элементов, а не количество байтов между ними. –

3

Что говорили Мауриц и Петер.

Интересно отметить в этой связи, что компиляторы могут сделать пустую оптимизацию базового класса (Ebco):

#include <iostream> 
struct Foo {}; 
struct Bar : Foo {}; 
int main() { 
    std::cout << sizeof(Foo) << ',' << sizeof(Bar) << std::endl;   
} 

Это, вероятно, напечатает «1,1», если скомпилировать и запустить его. См. Также Vandevoorde/Josuttis 16.2 по EBCO.

9

Класс без каких-либо элементов данных и функций-членов такой тип класса известен как пустой класс. Размер объекта пустого класса всегда 1 байт.

Когда мы создаем объект любого класса, в этот момент объект всегда получает 3 характеристики, т. Е.

  1. государственный
  2. Поведение
  3. Идентичность

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

+0

, если кто-то захочет переустановить 3 charecteristics объекта, то есть 1) Состояние 2) Поведение 3) Идентичность, тогда спросите меня – Shantanu

Смежные вопросы