Каковы недостатки использования unions
при хранении некоторой информации, например, серии байтов, и возможности доступа к ней сразу или по одному.
Пример: Цвет может быть представлен в RGBA. Таким образом, тип цвета может быть определен как,
typedef unsigned int RGBAColor;
Затем мы можем использовать «сдвиг и маскировку» битов, чтобы «получить или установить» красные, зеленые, синие, альфа-значения объекта RGBAColor (так же, как это делается в функциях Direct3D с помощью макрофункций, таких как: D3DCOLOR_ARGB()
).
Но что, если я использовал союз,
union RGBAColor
{
unsigned int Color;
struct RGBAColorComponents
{
unsigned char Red;
unsigned char Green;
unsigned char Blue;
unsigned char Alpha;
} Component;
};
Тогда мне не нужно будет всегда делать сдвиг (<<
) или маскировка (&
) для чтения или записи компонентов цвета. Но есть ли проблема с этим? (Я подозреваю, что это имеет некоторые проблемы, потому что я не видел, чтобы кто-нибудь использовал такой метод.)
Может ли Endianness быть проблемой? Если мы всегда используем Component
для доступа к цветным компонентам и использования Color
для доступа ко всему объекту (для копирования, назначения и т. д. в целом) порядок байтов не должен быть проблемой, верно?
— РЕДАКТИРОВАТЬ —
Я нашел старый пост, который является той же проблемой. Так что я думаю, что этот вопрос — своего рода репост: P извините за это. вот ссылка : Это хорошая практика, чтобы использовать союзы в C ++?
Судя по ответам, кажется, что использование союзов для данного примера нормально в C ++. Поскольку там нет изменения типа данных, есть только два способа получить доступ к одним и тем же данным. Пожалуйста, поправьте меня, если я ошибаюсь. Благодарю. 🙂
Такое использование объединений недопустимо в C ++, где объединение включает перекрывающиеся, но взаимоисключающие объекты. Вы не можете написать одного члена союза, а затем зачитать другого члена.
Это допустимо в C, где это рекомендуемый способ наказания типа.
Это относится к проблеме (строгого) псевдонимов, с которой сталкивается компилятор при попытке определить, различаются ли два объекта с разными типами. Языковые стандарты не согласны, потому что эксперты все еще выясняют, какие гарантии могут быть предоставлены без ущерба для производительности. Лично я избегаю всего этого. Что бы int
на самом деле быть использованы для? Безопасный способ перевести это скопировать байты, как memcpy
,
Существует также проблема порядка байтов, но имеет ли это значение, зависит от того, что вы хотите сделать с int
,
Я верю, используя союз решает любые проблемы, связанные с порядком байтов, так как, скорее всего, порядок RGBA определяется в сетевом порядке. Кроме того, тот факт, что каждый компонент будет uint8_t или около того, может помочь некоторым компиляторам использовать расширенную загрузку со знаком / нулем, сохраняя младшие 8 битов непосредственно в не выровненный байтовый указатель и даже будучи в состоянии распараллелить некоторые байтовые операции (например, рука имеет некоторые упакованные 4х8 битная инструкция).