Объединения

Объединение — это область памяти, используемая для хранения данных разных типов. В один момент времени в этой области могут храниться данные только одного типа. Размер объединения будет соответствовать размеру более сложного типа данных. Например, если внутри объединения определены переменные, имеющие типы int, float и double, то размер объединения будет соответствовать размеру типа double. Объявление объединения имеет следующий формат:

union [<Название объединения>] {
   <Тип данных> <Название члена 1>;
   ...
   <Тип данных> <Название члена N>;
} [<Объявления переменных через запятую>];

Точка с запятой в конце объявления является обязательной. Объявление только описывает новый тип данных, а не определяет переменную, поэтому память под нее не выделяется. Чтобы объявить переменную, ее название указывается после закрывающей фигурной скобки при объявлении объединения или отдельно, используя название объединения в качестве типа данных:

[union ]<Название объединения> <Названия переменных через запятую>;

В языке C++ ключевое слово union при объявлении переменной можно не указывать. После объявления переменной выделяется необходимый размер памяти. Пример объявления объединения и переменной:

union myUnion {
   int x;
   float y;
   double z;
} union1;

Пример отдельного объявления переменной:

myUnion union2;

Одновременно с объявлением переменной можно выполнить инициализацию первого члена объединения, указав значение внутри фигурных скобок:

myUnion union3 = {10};

Для инициализации произвольного члена объединения нужно после точки указать его название, а после оператора = — его значение:

myUnion union4 = {.z = 2.5};

Присвоить или получить значение можно с помощью точечной нотации:

<Переменная>.<Название члена> = <Значение>;
<Значение> = <Переменная>.<Название члена>;

Пример:

union1.x = 10;
std::cout << union1.x << std::endl; // 10

При использовании указателя на объединение доступ осуществляется так:

<Указатель> -> <Название члена> = <Значение>;
<Значение> = <Указатель> -> <Название члена>;

Пример:

myUnion *p = &union1;
p->x = 15;
std::cout << p->x << std::endl;     // 15
Можно также создавать анонимные вложенные объединения:
struct MyStruct {
   int a;
   union { // Анонимное вложенное объединение
      int b;
      double c;
   };
   int d;
};

Инициализация и доступ к полям осуществляется следующим образом:

MyStruct my_struct = {1, {.c = 2.5}, 4};
std::cout << my_struct.a << std::endl; // 1
std::cout << my_struct.c << std::endl; // 2.5
std::cout << my_struct.d << std::endl; // 4

В языке C++ объединения могут содержать функции, а также конструктор и деструктор. Объявления функций размещаются внутри объявления объединения, а определения функций — вне объявления. Перед названием функции указывается название объединения и оператор ::. Внутри функции к членам объединения можно обращаться без указания названия объединения. Пример использования объединений приведен в листинге 3.24.

Листинг 3.24. Объединения

#include <iostream>

union myUnion {
   int x;
   double y;
   void print_x();
   void print_y();
};

void myUnion::print_x() {
   std::cout << x << std::endl;
}
void myUnion::print_y() {
   std::cout << y << std::endl;
}
int main() {
   myUnion union1;
   union1.x = 10;
   union1.print_x(); // 10
   union1.y = 2.5;
   union1.print_y(); // 2.5
   // Определение размера объединения
   std::cout << sizeof(myUnion) << std::endl; // 8
   return 0;
}

Допускается не задавать одновременно название объединения и объявления переменных. В этом случае объединение называется безымянным или анонимным. Доступ к членам безымянных объединений осуществляется непосредственно по именам членов. Таким образом, названия членов объединений не должны конфликтовать с именами переменных, объявленных в том же пространстве имен. Безымянные объединения расположенные в глобальной области видимости или внутри пространства имен должны объявляться с помощью ключевого слова static. Пример использования безымянных объединений приведен в листинге 3.25.

Листинг 3.25. Безымянные (анонимные) объединения

#include <iostream>

static union { // static указывать обязательно
   int x;
   double y;
};

int main() {
   union { // Слово static не указывается
      int a;
      double b;
   };
   x = 12;
   std::cout << x << std::endl; // 12
   y = 11.5;
   std::cout << y << std::endl; // 11.5
   a = 458;
   std::cout << a << std::endl; // 458
   b = 1.7;
   std::cout << b << std::endl; // 1.7
   return 0;
}

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов