Наследование структуры С++ POD? Существуют ли какие-либо гарантии относительно расположения памяти производных членов
Скажем, у меня есть struct RGB
, и я хочу создать struct RGBA
, который наследует RGB
:
struct RGB {
unsigned char r;
unsigned char g;
unsigned char b;
};
struct RGBA: RGB {
unsigned char a;
};
Оба будут использоваться для чтения несжатых данных изображения:
RGBA *pixel=static_cast<RGBA *>(image->uncompressed_data);
Вопрос: Является ли это безопасным, относительно макета памяти struct RGBA
? Кто-нибудь гарантирует, что:
-
unsigned char a
появляется после RGB struct
(не раньше)
- Нет отступов между
struct RGB
и параметром из struct RGBA
?
будет #pragma pack
помочь здесь? Это все о макете памяти во время наследования.
Ответы
Ответ 1
Нет, макет не гарантируется. Единственные гарантии - это классы стандартного макета; и одно из условий такого класса состоит в том, что оно
либо не имеет нестатических членов данных в самом производном классе и не более одного базового класса с нестатическими членами данных, либо не имеет базовых классов с нестатическими элементами данных
Другими словами, все члены данных должны находиться в одном классе, а не в нескольких.
Ответ 2
Существует НЕТ, гарантирующий расположение макетов для дочерних элементов, а приведение НЕ безопасно.
Поскольку у вас есть наследование, также может быть отступы, это НЕ тривиально.
§ 9 Классы
1 POD struct109 - это класс, который как тривиальный класс, так и класс стандартного макета, и не имеет нестатических членов данных типа non-POD struct, non-POD union ( или массив таких типов). Аналогичным образом, объединение POD представляет собой объединение, которое является тривиальным классом и стандартным классом макета и не имеет не-
Также std::is_pod<RGBA>
не является POD
std::cout << std::boolalpha;
std::cout << std::is_pod<RGBA>::value << '\n';
Результат неверен. см. живая демонстрация
Ответ 3
Легко проверить наличие дополнений: Печать sizeof(RGB)
и sizeof(RGBA)
. Если это не 3 соответствующих 4, тогда структуры заполняются, и вам нужно удалить их.
В случае, если элемент a
появляется после b
, вы можете использовать offsetof
, чтобы проверить смещение каждого члена. Если смещение для a
на единицу больше смещения b
, то a
появляется непосредственно после b
.