c ++ sizeof () класса с функциями - PullRequest
22 голосов
/ 01 июля 2011

У меня вопрос на C ++. Я написал следующий класс:

class c
{
    int f(int x, int y){ return x; }
};

sizeof () класса c возвращает "1". Я действительно не понимаю, почему он возвращает 1.

Пытаясь лучше понять, что происходит, я добавил еще одну функцию:

class c
{
     int f(int x, int y){ return x; }
     int g(int x, int y){ return x; }
};

Теперь следующее действительно запутало меня! sizeof (c) по-прежнему равен 1 (!?!?!?!). Итак, я думаю, что функции не меняют размер класса, но почему ??? а почему размер равен 1? И зависит ли это от компилятора?

Спасибо! : -)

Ответы [ 7 ]

43 голосов
/ 01 июля 2011

Класс не содержит членов данных, поэтому он пуст.Стандарт требует, чтобы у каждого класса был хотя бы размер 1, так что вот что вы получите.(Функции-члены не являются физически «внутри» класса, на самом деле это просто бесплатные функции со скрытым аргументом, пространством имен и контролем доступа.)

11 голосов
/ 01 июля 2011

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

5 голосов
/ 01 июля 2011

Функции-члены, по сути, такие же, как и обычные функции, они просто получают скрытый параметр this. Таким образом, каждый экземпляр данного типа не должен носить с собой копии своих функций-членов; компилятор просто отслеживает обычные функции и предоставляет соответствующий параметр this для вас. Поэтому независимо от того, сколько функций имеет данный тип, нет необходимости изменять его размер. Когда вы попадаете в сложное наследование с виртуальными функциями и так далее, это немного меняется, но, в конце концов, количество функций по-прежнему не влияет на конечный размер объекта.

Первоначальный размер одного байта объясняется тем, что все объекты должны занимать некоторое пространство, так что вы можете быть уверены, что два объекта не займут одно и то же пространство. Рассмотрим массив ... a[5] - это то же самое, что и *(a + 5), и добавление к указателю увеличивает адрес памяти на размер объекта. если бы sizeof(a) было 0, то все элементы массива свернулись бы по одному и тому же адресу.

То, что тип объектов некоторого пространства определяется стандартом ... что размер, равный точно одному, не равен. sizeof(c) в вашем случае может быть 23, но для этого нет причин.

Для полноты картины подобъект может иметь нулевой размер. Оптимизация пустой базы позволяет базовому классу не занимать никакой фактической памяти, если в этом нет необходимости. Так что sizeof(Base) == sizeof(Derived) может быть правдой, хотя формально Derived содержит экземпляр Base, скрытый внутри него. Это разрешено стандартом, но не предписано им ... MSVC, например, не использует его в некоторых ситуациях.

1 голос
/ 01 июля 2011

1 означает 1 байт.И резонанс в том, что методы не хранятся внутри объекта.Они используются объектами , но не хранятся в них.Только члены класса хранятся в объектах.Попробуйте добавить простой элемент int или что-то еще и посмотрите, что произойдет.

0 голосов
/ 02 июля 2011

sizeof (char) == 1 всегда, потому что char является байтом, а sizeof возвращает количество байтов.(Тем не менее, байт не обязательно равен восьми битам.)

Абсолютно верно.Отсюда и термин «октет» (чтобы отличить то, что равно ровно 8 битам от более часто используемого термина «байт»).

Для получения дополнительной информации см. IEEE 1541:

http://en.wikipedia.org/wiki/IEEE_1541

0 голосов
/ 02 июля 2011

Q: Виртуальные функции занимают место для каждого объекта и, следовательно, увеличивают размер объекта?

A: Нет. Чем больше виртуальных функций, тем больше vtable. Чем больше подклассов, тем больше vtables. Если у класса нет виртуальных функций, то нет необходимости ни в vtable, ни в (для каждого объекта) vtable указателе.

Но нет это влияет на "sizeof". Сами функции занимают фиксированное количество места, независимо от того.

0 голосов
/ 01 июля 2011

Поскольку ваш класс является «ссылочной переменной» и для каждого MSDN: «Оператор sizeof никогда не возвращает 0 даже для пустого класса».

Пример: #include <stdio.h></p> <p>class c { public: int f(int x, int y){ return x; } int g(int x, int y){ return x; } };</p> <p>struct s { int f; int g; };</p> <p>int main (int argc, char *argv[]) { c objc; s objs; printf ("sizeof (c)= %d, sizeof (objc)= %d, sizeof (class c)= %d...\n", sizeof (c), sizeof (objc), sizeof (class c)); printf ("sizeof (s)= %d, sizeof (objs)= %d, sizeof (struct s)= %d...\n", sizeof (s), sizeof (objs), sizeof (struct s)); return 0; }

РЕЗУЛЬТАТ:

sizeof (c)= 1, sizeof (objc)= 1, sizeof (class c)= 1...
sizeof (s)= 8, sizeof (objs)= 8, sizeof (struct s)= 8...

Обратите внимание также на разницу между "struct" и "class".

Вот больше информации:

http://www.geekinterview.com/question_details/42847

...