logo
volkov / C++ / Бьерн Страуструп-Справочное руководство по С++

R.9.5 Объединения

Объединение можно представить как структуру, все члены имеют

нулевое смещения, а размер ее достаточно велик, чтобы

вмещать любой из ее членов. В любой момент времени объединение

может содержать только один член. В объединении могут быть

функции-члены (в том числе конструкторы и деструкторы), но не

виртуальные функции ($$R.10.2). Объединение не может иметь базовых

классов и не может само использоваться в качестве базового класса.

Членом объединения не может быть объект класса с конструктором или

деструктором, а также с определенной пользователем операцией

присваивания ($$R.13.4.3). Объединение не может содержать статических

членов, представляющих данные.

Объединение вида

union { список-членов }

называется безымянным объединением, оно определяет объект без имени

(и без типа). Имена всех членов безымянного объединения должны

отличаться от других имен в той области видимости, в которой описано

объединение; их можно использовать в этой области видимости

непосредственно, без обычных операций доступа к членам ($$R.5.2.4).

Приведем пример:

void f()

{

union { int a; char* p; };

a = 1;

// ...

p = "Jennifer";

// ...

}

Здесь a и p используются как обычные переменные (не члены), но поскольку

они входят в одно объединение, их адреса совпадают.

Глобальные безымянные объединения можно описать со спецификацией

static. Безымянные объединения не должны содержать частных или

защищенных членов ($$R.11), а также функций-членов.

Если описаны объекты объединения или указатели на него, то

оно не считается безымянным, например,

union { int aa; char* p; } obj, *ptr=&obj;

aa = 1; // ошибка

ptr->aa = 1; // нормально

Здесь присваивание простому имени aa незаконно, т.к. имя члена не

привязано ни к какому объекту.

Инициализация объединений, не имеющих конструкторов, описывается

в $$R.8.4.1.