Особым видом структур данных является объединение. Определение объединения напоминает определение структуры, только вместо ключевого слова struct используется union:
union number { short sx; long lx; double dx;};
В отличие от структуры, все атрибуты объединения располагаются по одному адресу. Под объединение выделяется столько памяти, сколько нужно для хранения наибольшего атрибута объединения. Объединения применяются в тех случаях, когда в один момент времени используется только один атрибут объединения и, прежде всего, для экономии памяти. Предположим, нам нужно определить структуру, которая хранит "универсальное" число, т.е. число одного из предопределенных типов, и признак типа. Это можно сделать следующим образом:
struct Value { enum NumberType { ShortType, LongType, DoubleType }; NumberType type; short sx; // если type равен ShortType long lx; // если type равен LongType double dx; // если type равен DoubleType};
Атрибут type содержит тип хранимого числа, а соответствующий атрибут структуры – значение числа.
Value shortVal;shortVal.type = Value::ShortType;shortVal.sx = 15;
Хотя память выделяется под все три атрибута sx, ls и dx, реально используется только один из них. Сэкономить память можно, используя объединение:
struct Value { enum NumberType { ShortType, LongType, DoubleType }; NumberType type; union number { short sx; long lx; double dx; } val;}; // если type равен ShortType // если type равен LongType // если type равен DoubleType
Теперь память выделена только для максимального из этих трех атрибутов (в данном случае dx). Однако и обращаться с объединением надо осторожно. Поскольку все три атрибута делят одну и ту же область памяти, изменение одного из них означает изменение всех остальных. На рисунке поясняется выделение памяти под объединение. В обоих случаях мы предполагаем, что структура расположена по адресу 1000. Объединение располагает все три своих атрибута по одному и тому же адресу.
Замечание. Объединения существовали в языке Си, откуда без изменений и перешли в C++. Использование наследования классов, описанное в следующей главе, позволяет во многих случаях добиться того же эффекта без использования объединений, причем программа будет более надежной.
Рис. 9.1. Использование памяти в объединениях.