CPP tutorials

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;
}
Output

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;
}
Output

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;
}
Output

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.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button