Некоторые, но не все средства класса объединения применяются одинаково. У класса объединения не может быть члена, являющегося ссылкой, но у него могут быть члены большинства других типов, включая, согласно новому стандарту, типы классов с конструкторами или деструкторами. Объединение может использовать спецификаторы доступа, чтобы сделать члены открытыми закрытыми, или защищенными. По умолчанию, как и у структуры, члены объединения являются открытыми.
Класс объединения может определять функции-члены, включая конструкторы и деструкторы. Но объединения не могут происходить от другого класса и не могут быть использованы как базовый класс. В результате у объединения не может быть виртуальных функций.
Объединения позволяют создать набор взаимоисключающих значений, которые могут иметь разные типы. Предположим, например, что существует процесс, в ходе которого обрабатываются различные виды числовых или символьных данных. Для хранения этих значений можно было бы использовать следующее объединение.
// объект типа Token способен содержать один член, имеющий любой из
// следующих типов
union Token {
// члены по умолчанию открыты
char cval;
int ival;
double dval;
};
Определение объединения начинается с ключевого слова union, за которым следует имя объединения (не обязательно) и набор его членов, заключенный в фигурные скобки. Этот код определяет объединение по имени Token, способное содержать значение типа char, int или double.
Имя объединения — это имя типа. Подобно встроенным типам, по умолчанию объединения не инициализированы. Объединение можно явно инициализировать таким же образом, как и агрегатные классы (см. раздел 7.5.5), — при помощи инициализаторов, заключенных в фигурные скобки:
Token first_token = {'a'}; // инициализирует член cval
Token last_token; // не инициализированный объект Token
Token *pt = new Token; // указатель на не инициализированный
// объект Token
Если инициализатор есть, он используется для инициализации первого члена. Следовательно, инициализация объединения first_token присваивает значение его члену cval.
К членам объекта типа объединения обращаются при помощи обычных операторов доступа к члену:
last_token.cval = 'z';
pt->ival = 42;
Присвоение значения переменной-члену объекта объединения делает другие его переменные-члены неопределенными. В результате при использовании объединения следует всегда знать, какое именно значение в настоящее время хранится в нем. В зависимости от типов членов возвращение или присвоение хранимого в объединении значения при помощи неправильной переменной-члена может привести к аварийному отказу или неправильному поведению программы.
Анонимное объединение (anonymous union) — это безымянное объединение, не содержащее объявлений между закрывающей фигурной скобкой, завершающей его тело, и точкой с запятой, завершающей определение объединения (см. раздел 2.6.1). При определении анонимного объединения компилятор автоматически создает безымянный объект только что определенного типа объединения:
union { // анонимное объединение
char cval;
int ival;
double dval;
}; // определяет безымянный объект, к членам которого можно обращаться
// непосредственно
cval = 'c'; // присваивает новое значение безымянному, анонимному
// объекту объединения
ival = 42; // теперь этот объект содержит значение 42
Члены анонимного объединения непосредственно доступны в той области видимости, где определено анонимное объединение.