Вопрос по c++, struct, language-lawyer, c, class – Как структура памяти класса против структуры

10

Я пришел из C-программирования, где данные в структуре располагаются сначала с верхней переменной, затем со второй, третьей и так далее.

Я сейчас программирую на C ++ и вместо этого использую класс. Я в основном хочу добиться того же, но я также хочу получить методы get / set, а также, возможно, другие методы (я также хочу попробовать сделать это в стиле C ++ и, возможно, узнать что-то новое).

Есть ли гарантия, например, что публичные переменные будут сначала в памяти, а затем приватные?

Зачем вам нужно знать, как данные располагаются в памяти? Я знаю, это приятно понимать, но во многих случаях на практике, если вам нужно знать, это может указывать на то, что вы делаете что-то не так ... psmears
Так что, если я сначала определю публичные переменные, они будут первыми в памяти? И я предполагаю, что таким образом я могу получить доступ к закрытым пользователям? iQt
Разница лишь в правах доступа. Правило большого пальца держать горячие переменные наверху. 101010
У меня есть байтовый массив с данными, которые получены, и я хочу быть в состоянии привести к типу этого класса. Таким образом, все поля данных будут установлены в одну строку. РЕДАКТИРОВАТЬ: Это может не работать, если функции занимают память ... Я думаю, структура это то, что мне нужно = / iQt

Ваш Ответ

2   ответа
16

Есть ли гарантия, например, что публичные переменные будут сначала в памяти, а затем приватные?

Нет, такая гарантияне сделано - стандарт C ++ 11, [class.mem] / 14:

Нестатические члены данных (не объединенного) класса стот же контроль доступа (Раздел 11) распределяются так, чтобы более поздние члены имели более высокие адреса в объекте класса.Порядок распределения нестатических элементов данных с различным контролем доступа не определен (11).

Так

struct A
{
    int i, j;
    std::string str;

private:

    float f;

protected:

    double d;
};

Гарантируется, что для данного объекта типаA,

i имеет меньший адрес, чемj а такжеj имеет меньший адрес, чемstr

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

Это говорит только о порядке, но не о том, что первая переменная действительно начинается с «первого адреса»? Предположим, что класс без наследования.

Да, но только длястандартные классы, Существует ряд требований, которым должен удовлетворять класс, чтобы быть классом стандартной компоновки, и одно из них заключается в том, что все члены имеют одинаковый контроль доступа.
Цитирование C ++ 14 (то же самое относится к C ++ 11, но формулировка более косвенная), [class.mem] / 19:

Если объект класса стандартной компоновки имеет какие-либо нестатические элементы данных, его адрес совпадает с адресом его первого нестатического члена данных. В противном случае его адрес совпадает с адресом его первого базового объекта (если есть). [ЗаметкаПоэтому в объекте структуры стандартной компоновки может быть безымянный отступ, но не в его начале, что необходимо для достижения соответствующего выравнивания.- конец примечания ]

[Класс] / 7:

A стандартная компоновка это класс, который:

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

110) Это гарантирует, что два подобъекта, которые имеют один и тот же тип класса и принадлежат к одному и тому же самому производному объекту, не будут распределены по одному и тому же адресу (5.10).

@Phataas Хорошо, смотри в нижней части моего ответа Columbo
Позволь нампродолжить это обсуждение в чате. Columbo
Это дало мне хорошее понимание и было очень хорошо объяснено! Я думал об использовании класса, чтобы иметь возможность приводить к этому классу указатель на начало массива, но теперь я не уверен, возможно ли это из-за функций-членов метода доступа и других возможных дополнений и т. Д. объем памяти? iQt
Так что я не могу предположить, что они в последовательном порядке, если у меня есть как открытые, так и частные переменные? Что делать, если у меня есть только публичный или только частный? iQt
5

Первое первым:class а такжеstruct в C ++ очень похожи - единственная разница в том, что все члены перед первым спецификатором доступа вclass считаются частными, а вstruct они публичные.

Есть ли гарантия, например, что публичные переменные будут сначала в памяти, а затем приватные?

Там нет такой гарантии. Когда нет наследования, память будет выделена членам класса в порядке, в котором вы объявляете их в той же группе доступа. Компилятор должен решить, следует ли размещать общедоступные переменные-члены перед частными / защищенными или наоборот. Как и C, C ++ может добавлять отступы между членами класса.

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

Я в основном хочу добиться того же [макета], но я также хочу получить методы get / set и, возможно, другие методы.

Если вы сделаете все члены данных вашего класса приватными и добавите функции-члены-аксессоры (это то, что C ++ называет «методами» из других языков), вы добьетесь этого эффекта.

Похожие вопросы