#cpp #память #структуры
Прочитал, что поля структуры хранятся в памяти последовательно(в порядке объявления) (+- платформ.зависимое выравнивание). Вопрос такой: как влияют методы в структурах на их расположение в памяти? Предположим, есть структура вида: struct my_Struct{ double n; void meth(); char ch; } Как экземпляр этой структуры (а именно его поля) будут расположены в памяти? И ещё, применимы ли все знания по структурам(и их расположению в памяти) к классам? И есть ли какая-то разница (с точки зрения памяти) между обычными методами и перегрузками / конструкторами / деструкторами?
Ответы
Ответ 1
Во-первых, как правильно заметили в комментариях, в С++ структур нет. Ключевое слово struct создает классы, в которых поля и родители по умолчанию публичные. Какой-то другой разницы между struct и class, с точки зрения стандарта, насколько я знаю, нет. Поля классов хранятся в порядке объявления только если спецификатор доступа (public/private/protected) у них одинаковый. Если спецификатор доступа одинаковый, то из двух полей в памяти идет раньше то, которое в определении класса написано выше. Если спецификатор доступа у двух полей разный, то компилятор вправе расположить их относительно друг друга как угодно. В частности, соответствующий стандарту компилятор может располагать все поля в памяти по порядку, игнорируя спецификаторы доступа. А может сложить в кучку отдельно private, protected и public. Могут быть какие-то другие варианты. Пруф: [class.mem]/19 Non-static data members of a (non-union) class with the same access control are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified. Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions and virtual base classes. У каждого экземпляра одного класса, очевидно, свой набор из всех нужных полей. Но вот методы у всех экземпляров одного класса общие - они не занимают место в экземплярах класса и не влияют на его размер в байтах.* (Не считая указателя на vtable для виртуальных функций.) Обычно методы реализуются так же, как и обычные функции, но с добавленным невидимым параметром this. Так что нет смысла в каждом экземпляре хранить какую-то информацию о методах, не считая vtable pointer. *Хотя разницы между class и struct быть не должно, и хотя не виртуальные методы на размер класса влиять не должны, мне у нас на SO недавно попался пример, в котором GCC с определенными настройками убирал выравнивание из struct как только к нему добавляли один любой метод, либо когда struct меняли на class. Видимо для совместимости с каким-то С-шным компилятором. Если кто-то найдет больше информации по этой теме, буду благодарен.Ответ 2
Методы никак не влияют на расположение в памяти (посмотреть). Методы априори не могут занимать память объектов (методы ведь не создаются для каждого объекта отдельно). Метод - (на низком уровне) это функция для которой просто передается указатель this с помощью регистра процессора. Из ранее приведенной ссылки: lea rax, [rbp-12] - взятие адреса объекта (начала последовательности байт принадлежащих объекту) и помещение его в регистр. Далее метод будет работать как обычная функция, зная, что в нужном регистре хранится указатель на текущий объект. Различие между структурой и классом только в доступности по умолчанию: структуры - public, классы - private (все члены по умолчанию имеют указанный спецификатор доступа) (class). Перегруженные функции - это разные функции (каждая из них имеет собственный адрес). Какая именно функция будет вызвана компилятор решит во время компиляции (в отличии от виртуальных методов). Посмотреть.
Комментариев нет:
Отправить комментарий