Рассмотрим следующие две структуры:
struct A
{
// A bunch of standard layout data
};
struct B:public A
{
// Other data
};
И объект
B foo;
Предположим, что sizeof (A) не отличается между компиляторами, упаковка одинакова, и B не добавляет никаких виртуальных методов, поэтому члены A будут иметь один и тот же адрес по отношению к &foo при компиляции с использованием gcc или msvc для платформы Windows x86 или x86-64?
РЕДАКТИРОВАТЬ: Я понял, что лучший способ реализовать наследование, это поместить A перед B. В противном случае, upcast потребует смещения указателя this на sizeof (B), что глупо. По крайней мере, GCC помещает содержание B после содержания A.
Архитектура x86_64 является проблемой, GCC и MSVC выбрали разные модели памяти. GCC — это LP64, MSVC — это LLP64. Другими словами, долго тип — 64-битный в GCC, 32-битный в MSVC.
«Тот же адрес» довольно неоднозначен в этом вопросе, но, очевидно, у вас возникнет проблема, если A и B не скомпилированы одним и тем же компилятором. В этом случае, возможно, другая упаковка также будет проблемой. Интерполяция из той же неоднозначности, если B содержит какие-либо виртуальные элементы, а A нет, то расположение A и B несовместимо. B будет вставлен указатель v-таблицы.
Ганс все правильно объяснил. Общий ответ НЕТ. Это не будет работать из коробки для любого класса / компилятора и т. Д.
Тем не менее. C ++ имеет такие функции, как #pragma pack
запись выравнивания в классе и т. д. Все эти вещи предназначены для создания требуемой или предопределенной схемы памяти. Если вы будете осторожно использовать их (возможно, с некоторыми #ifdefs
также), у вас будет совместимость, которую вы хотите. Это использовалось в тоннах проектов, и это работало.
Но все же вам придется тщательно проверять макеты для каждого компилятора, который вы используете.