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