Расположение класса в C++: Почему участникам иногда приказывают?

Вы четко указываете FTP-серверу, что вы хотите передачу BINARY, а не передачу ASCII?

9
задан Jonathan Leffler 7 April 2012 в 19:42
поделиться

4 ответа

Эта свобода лишает возможности в теории связывать двоичные файлы, созданные различными компиляторами.

Это невозможно по ряду причин, и структурный макет является самым незначительным. vtables, реализации operator new и delete, размеры типа данных...

Таким образом, каковы остающиеся причины строгого упорядочивания в разделе?

C совместимость, я думал бы, так, чтобы структура, определенная в C, упаковала тот же способ, которым это делает в C++ для данного набора компилятора.

И новый C++ 0911 стандартов позволяют полностью определять структуры объекта "вручную"?

Нет, не больше, чем текущий стандарт делает.

Для a class или struct без vtable и совершенно частного (или общественность) поля, тем не менее, уже возможно, если Вы используете [u]int[8|16|32|64]_t типы. Для какого варианта использования Вы имеете больше, чем это?

8
ответ дан 4 December 2019 в 21:13
поделиться

[редактирование] я изучил что-то новое сегодня! найденный следующей стандартной кавычкой:

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

Интересный - я понятия не имею, почему эта степень свободы дана. Продолжение к th отдыху моего предыдущего ответа...


Как упомянуто, причиной сохранения упорядочивания является совместимость C, и тогда я предполагаю, что никто не думал о преимуществах переупорядочения участников, в то время как расположение памяти обычно делалось вручную так или иначе. Кроме того, что теперь считали бы "ужасными приемами" (как обнуление выбранных участников с memset, или наличие двух структур с тем же расположением) были довольно распространены.

Стандарт не дает Вам, способ осуществить данное расположение, но большинство компиляторов обеспечивает меры для управления дополнением, например, пакетом #pragma на компиляторах MSVC.

Причиной автоматического дополнения является мобильность платформы: различная архитектура имеет различные требования выравнивания, например, некоторый бросок архитектуры на неправильно выровненном ints (и они были простыми случаями тогда).

2
ответ дан 4 December 2019 в 21:13
поделиться

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

Одной причиной компилятор является бесплатным командовать разделы доступа, мог бы быть так компилятор, мог установить порядок на разделы доступа: участники с более низкими адресами более защищены, чем участники с более высокими адресами, например.

Вы ничего не получили бы, если бы то переупорядочение не было позволено: Только ПЕРЕХОДНЫЕ ПРИСТАВКИ обеспечивают совместимость C и способ дать Вам байтовые смещения участников в классе/структуре (использующий макрос offsetof) или позволяет Вам memcpy их. Тип станет не-POD, если Вы определите пользовательского конструктора, скопируете конструктора, члена парламента, не занимающего официального поста или некоторый другой материал. В частности, получение из класса в настоящее время повреждает PODness.

C++ 1x понижает требования для ПЕРЕХОДНЫХ ПРИСТАВОК. Например, в C++ 1x std::pair<T, U> на самом деле POD, даже при том, что он предоставляет своему собственному конструктору (который должен соответствовать определенным правилам хотя).

0
ответ дан 4 December 2019 в 21:13
поделиться

Править: Я боюсь, что неправильно понял Ваш вопрос

Я думаю, что это - оптимизация для доступа к памяти. Например, если мы получили эту структуру:

struct example
{
   int16 intData;
   byte  byteData;
   int32 intData;
   byte intData;
   int32 intData;
}

Давайте предположим, что слово в этой платформе составляет 32 бита. Затем Вам будут нужны 4 полных слова для передачи всех данных в структуре:

int16 + байт = 24 бита (netx поле не соответствует здесь),

int32 = 32 бита (netx поле не соответствует здесь),

байт = 8 битов (netx поле не соответствует здесь),

int32 = 32 бита

Но если Вы перестраиваете поля к:

struct example
{
   int16 intData;
   byte  byteData;
   byte intData;
   int32 intData;
   int32 intData;
}

затем можно сохранить один доступ к памяти.

0
ответ дан 4 December 2019 в 21:13
поделиться
Другие вопросы по тегам:

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