2011-08-01 1 views
7

С кодом:Sizeof пустого класс

#include <iostream> 

class A {}; 
class B { char x; }; 

int main() 
{ 
    std::cerr << sizeof(A) << " " << sizeof(B) << std::endl; 
} 

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

Мой вопрос: что хранится в этом «1» байте для пустого класса (я предполагаю, что он пуст), и что делает компилятор внутренне, чтобы сделать его так, чтобы sizeof B был таким же, как sizeof A в этом случае?

Я хотел бы полностью понять это, а не просто знать ответ.

+0

Это зависит от реализации компилятора. Возникает также вопрос: почему вас это волнует? –

+8

Кто спрашивает об этом в интервью? Это ужасный вопрос интервью. – nmichaels

+2

Посмотрите здесь: http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class – a1ex07

ответ

8

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

Единственная причина этого правила заключается в том, что объекты должны быть однозначно идентифицируемыми. Объект идентифицируется по адресу, который он имеет в памяти. Чтобы два объекта не имели одного и того же адреса (кроме объектов базового класса), объекты пустых классов «занимают» память с ненулевым размером.

+0

Тем не менее ИМХО - это очень слабый аргумент. Итак, что, если два * пустых * объекта действительно разделяют их начальный адрес? Я считаю, что это было хорошо во времена K & R C, когда не было смысла создавать * пустые * объекты в любом случае. OTOH с появлением вещей C++ изменилось. Вы можете захотеть иметь пустой объект с нетривиальным d'tor.Плюс пустые объекты могут возникать в метапрограмме шаблона – valdo

+4

@valdo Это неправильное представление. Уникальная идентификация объектов * необходима *. Объекты в C++ определяются * памятью, которую они занимают (объект = местоположение памяти по определению). Если объекты будут иметь общий адрес, среда выполнения не сможет их отличить. Это нарушит все предположения, лежащие в основе системы типа C++. Чтобы дать только один конкретный пример, он разбил бы массивы и арифметику указателя. –

4

В стандарте C++ нет требования о том, чтобы пустой объект должен иметь один байт занимаемой памяти. Это чисто основано на реализации.

EDIT: верно, это соответствуя (ISO/IEC 14882 с.149):

9 Классы [класс]
..
..
..
3 Полные объекты и подобъекты члены тип класса должен иметь ненулевой размер ...

+2

Это * - это требование, однако, что объекты однозначно идентифицируются по их разному адресу (или типу). –

+1

@cprogrammer - Он не должен быть одним байтом, он также может быть двоим. :) –

0

Вы часто можете увидеть подобный эффект в классах, как это:

class Foo { 
    int a; 
    char b; 
}; // sizeof(Foo) > sizeof(int) + sizeof(char) 

Не все памяти в объекте C++ необходимо иметь имя. Unnames memory внутри объекта commnoly называется «padding». У вашего пустого класса есть один байт заполнения. Одна из наиболее распространенных причин, по которым компиляторы C++ вставляют прописку, - это разрешить использование класса в типе массива.

+0

Это правильно, но в случае пустых классов действует другой эффект, как объясняют другие ответы. Пустые классы должны иметь ненулевой размер, потому что это требует стандарт C++, но дополнение - это то, что компиляторы предпочитают реализовать. –

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