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

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.