Почему размер класса зависит только от членов данных, а не от функций-членов?

Я хочу узнать подробное описание размера класса. Я хочу знать, есть ли только члены данных и функция-член без какого-либо виртуального ключевого слова, то почему размер класса зависит только от членов данных. Например, для:

class A {
    int a;
public:
    int display() { 
    cout << "A=" << a << endl;
   }
};

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

Спасибо

Ответ 1

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

Например, представьте себе это следующим образом:

int display(A* thisptr)
{
   //do something
   printf("%d",thisptr->a); 
   return;
}

Таким образом, функция отображения сохраняется как простая функция с одним дополнительным параметром. Имя, хотя и искажено, зависит от компилятора.

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

Ответ 2

Это зависит от реализации - оно не указано в стандарте. Однако вы правы, не виртуальные функции-члены (и даже виртуальные функции после первого) не влияют на размер класса.

Это потому, что он будет использовать много памяти, если каждый экземпляр класса будет иметь указатели на все функции. И почему они? Во время выполнения объект знает, какой тип он есть, и он может вызвать соответствующую функцию. И одна и та же функция идентична между экземплярами, все, что отличается, является объектом, на котором он работает, который передается как параметр под капотом.

Ответ 3

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

Исполняемый код не будет иметь sizeof, так как они не занимают место в стеке или куче, а программа работает. Он сохраняется в исполняемом изображении и загружается один раз ОС при запуске программы.

Ответ 4

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

Ответ 5

За исключением скрытых членов данных, внедренных для реализации виртуальных функций и виртуального наследования, размер экземпляра определяется только членами данных классов и базовыми классами. Из С++: Under the Hood (1994) Если вы хотите узнать больше.

Ответ 6

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

Ответ 7

Поскольку состояние функции уходит в стек и создается/удаляется при входе/выходе функции.

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

Подумайте,

A a1, a2;

a1.a и a2.a разные, но a1.display() и a2.dispaly() - это один и тот же код функции (подумайте int A::display()) как int display(A* this))