Почему размер класса зависит только от членов данных, а не от функций-членов?
Я хочу узнать подробное описание размера класса.
Я хочу знать, есть ли только члены данных и функция-член без какого-либо виртуального ключевого слова, то почему размер класса зависит только от членов данных.
Например, для:
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)
)