C++ Unions

In C++, a union is a user-defined data type that can hold members of different data types.
- Unlike structures, all members of a union are stored in the same memory location.
- Since all members share the same memory, changing the value of one member overwrites the value of the others.
The size of the union will always be equal to the size of the largest member of the union. All the less-sized elements can store the data in the same space without any overflow. Let’s take a look at the code example:
C++
#include <iostream>
using namespace std;
union A {
int x;
char y;
};
union B {
int arr[10];
char y;
};
int main()
{
// Finding size using sizeof() operator
cout << "Sizeof A: " << sizeof(A) << endl;
cout << "Sizeof B: " << sizeof(B) << endl;
return 0;
}
Sizeof A: 4 Sizeof B: 40
The above union’s memory can be visualized as shown:
Union Declaration
A union is declared similarly to a structure. Provide the name of the union and define its member variables:
C++
union union_Name {
type1 member1;
type2 member2;
..
};
After declaration of a union then create a variable of union like below:
C++
union_name variable_name;
We can also declare a variable at the declaration of union.
C++
union union_Name {
type1 member1;
type2 member2;
.
.
}variable_name;
C++
#include <iostream>
using namespace std;
// Define a union with different data types
union Student {
int rollNo;
float height;
char firstLetter;
};
int main()
{
// Declare a union variable
Student data;
data.rollNo = 21;
cout << data.rollNo << endl;
data.height = 5.2;
cout << data.height << endl;
data.firstLetter = 'N';
cout << data.firstLetter << endl;
return 0;
}
21 5.2 N
Nested Union
A union can be defined within a structure, class or another union, known as a nested union. This approach helps efficiently organize and access related data while sharing memory among the union’s members.
Syntax
C++
union name1 {
// Data members of Name1
union name2 {
// Data members of Name2
} inner;
};
Accessing members of union using dot(.) operator:
C++
name1 obj;
obj.inner.member;
Example:
C++
#include <iostream>
using namespace std;
// Define a structure containing a nested union
struct Employee
{
char name[50];
int id;
// Nested union
union Pay {
float hourlyRate;
float salary;
} payment;
};
int main()
{
Employee e1;
e1.id = 101;
// Access nested union member using dot operator
e1.payment.hourlyRate = 300.0;
cout << "Employee ID: " << e1.id << "\n";
cout << "Hourly Rate: Rs " << e1.payment.hourlyRate << endl;
// You can also assign salary if needed
e1.payment.salary = 50000.0;
cout << "Salary: Rs " << e1.payment.salary << endl;
return 0;
}
Employee ID: 101 Hourly Rate: Rs 300 Salary: Rs 50000
Anonymous Unions
Anonymous unions are those unions that are declared without any name inside a main function. As we do not define any union name, we can directly access the data members of the union that is why their members must be declared with unique names to avoid ambiguity in the current scope.
They are mostly used in nested unions where they can be accessed as if they are the members of the outer union/structure.
C++
#include <iostream>
using namespace std;
struct Employee
{
int id;
// Anonymous union
union {
float hourlyRate;
float salary;
};
};
int main()
{
Employee e1;
e1.id = 101;
// Access anonymous union member
e1.hourlyRate = 300;
cout << "Employee ID: " << e1.id << "\n";
cout << "Hourly Rate: Rs " << e1.hourlyRate << endl;
// Only one member is active at a time
e1.salary = 50000;
cout << "Salary: Rs " << e1.salary << endl;
return 0;
}
Applications of Union in C++
- Used for memory efficiency, particularly in embedded systems or situations where memory is a critical resource. By having different data types share the same memory, they reduce the overall memory footprint compared to a structure.
- Used to map to hardware registers that might have different interpretations depending on the context (e.g., a register that can be read as a status flag or written as a command).
- Suitable for representing data that can take on one of several different types but never simultaneously. For instance, a message packet might contain either an integer ID or a string message, but not both at once.