C++ Unions

Unions in C++ are a special data structure that is defined using the union keyword, which stores different data types in the same memory location. Also, in a union, only one member can store a value at a time. In this article, we will discuss what is a union in C++, creating a union, assigning and accessing a union, the size of a union, nested unions, anonymous unions, local and global unions, unrestricted unions, union-like classes, and best practices for using a union in C++.

 

Table of Contents:

What is a Union in C++?

A union in C++ is a special data structure that allows for storing different data types in the same memory location. It allocates enough memory to store the largest member, which means that at any given time, it can store a value of only one of its members. The size of the union is determined by the largest member.

Syntax:

union UnionName {
type member1;
type member2;
// other members...
};

Here,

  • union: It is a keyword used to define a union.
  • UnionName: It is the name of the union, which can be any valid identifier. 
  • type: It can be any valid C++ data type, such as int, float, char, etc.
  • member1, member2: These are the members of the union.

Creating a Union in C++

Creating a union is simple in C++. Below is a step-by-step procedure for defining, declaring, and using a union in C++:

1. Declaring a Union

At first, declare a union using the union keyword followed by the union name and its members using the given syntax.

Syntax:

union UnionName {
type member1;
type member2;
// other members...
};

2. Creating a Union Variable

Now, a union variable can be created once a union is declared.

Syntax:

UnionName variableName;

A union variable can also be created during defining the union.

Example:

union Data {
int intValue;
float floatValue;
char charValue;
} d;

Accessing and Assigning a Union in C++

Accessing and assigning values to the union members in C++ is also simple and easy. The member that was recently assigned can only be read because of the shared memory feature of the unions. Also, accessing any other member than the recently assigned one will lead to undefined behavior.

1. Assigning a Union

A value can be assigned to a union member using the assignment operator in C++.

Example:

Cpp

Output:

Assigning a Union

The code shows how union members are assigned and accessed in C++, since all the members share the same memory, thus, each new assignment overwrites the previous one, and then the result is printed to the console.

2. Accessing Union Members

The dot operator (.) in C++ can be used to access the union members. Also, the arrow operator (->) can be used to access a union member.

Example:

Cpp

Output:

Accessing Union Members

The code shows how the union members are accessed using the dot (.) operator, and only recently assigned member charVal stores a valid value due to the shared memory, which is then printed to the console.

Size of a Union in C++

Since all the members share the same memory location, thus, the size of a union is equal to the largest member of the union.

Example:

Cpp

Output:

Size of a Union in C++

The code shows that the size of a union Data 4 bytes, which is equal to the size of its largest member, is determined and printed to the console.

Nested Unions in C++

A nested union in C++ is a union that can contain another union as a member. It is used when there is a need to organize the related data in the same memory location.

Syntax:

union OuterUnion {
data_type1 outerMember1;
data_type2 outerMember2;

union InnerUnion {
data_type3 innerMember1;
data_type4 innerMember2;
} innerUnionVar; // Optional variable name
};

A nested member can be accessed using the dot (.) operator in C++.

outer.inner.member

Example:

Cpp

Output:

Nested Unions in C++

The code shows how a nested union is defined, and values are assigned to id, info.marks, info.grade, which overwrites the previous value, and then all the members with values are printed to the console as a result.

Anonymous Unions in C++

An anonymous union in C++ is a union without a name that is directly declared in a scope such as global, namespace, class, or struct. The members of the anonymous union as accessed directly without any variable or union name. Also, members of an anonymous union must not have any access specifiers if the members are declared outside of the class.

Example:

Cpp

Output:

Anonymous Unions in C++

The code shows how an anonymous union is used inside a structure in which the union members, hourlyWage and salary, are accessed directly without any union name, and the salary is printed to the console after being assigned.

Need for Unions in C++ 

  • Unions are needed in C++ because they save memory space by sharing space between all the members.
  • In a union, only one member can store a valid value at a time.
  • Unions are useful in embedded systems and also in performance-based applications.
  • A union is ideal for type-punning and low-level data interpretation.
  • They also help to store only one value at a time out of several possible types in a single variable.

Get 100% Hike!

Master Most in Demand Skills Now!

Local and Global Unions in C++

A union can be declared at both global and local scopes based on its use cases.

1. Global Union

A global union is declared outside of all the functions in the program. It can be accessed through a file or a program. It is used across multiple functions. Also, it can maintain its value until the program runs.

Example:

Cpp

Output:

Global Union

The code shows how a global union, GlobalData, is declared outside the main function and also allows its variable g to be accessed and modified in the program.

2. Local Union

A local union is defined inside a function and is accessible only within the scope of that function. It is used when the union is needed temporarily and does not need to be visible globally.

Example:

Cpp

Output:

Local Union

The code shows how a local union, LocalData, is defined in the main function, in which the ch member is assigned a value, and then the values are accessed and printed to the console.

Unrestricted Unions in C++ (C++11 and Later)

The unrestricted unions in C++11 and the later versions can have non-trivial types such as std::string or classes with constructors and destructors. But they need manual construction and destruction of such members by using the placement new operator and by calling destructors explicitly.

Example:

Cpp

Output:

Unrestricted Unions

The code shows how an unrestricted union, which has a std::string, and the constructor and destructor are manually defined to manage this non-trivial data type member, and then it is printed with the value to the console.

Union-like Classes in C++

Union-like classes in C++ are the classes that behave like unions, as they store different types in the same memory space, but with safety and control. The union-like classes can be implemented manually using the std::variant or manual memory management.

Why Use Union-like Classes?

  • Because they provide type safety and control better than the raw unions.
  • They allow non-trivial types and constructors to be used in the program.
  • They also support tagged unions by tracking the active type in the program.

Example:

Cpp

Output:

Union-like Classes

The code shows how a union-like class Wallet stores either an integer cash amount or a card name and simulates how a real wallet carries either, but not both, at once. It uses an enum for tracking the active member, and then prints the current value to the console.

Difference between Union and Structure in C++

Aspect Union Structure
Memory Shares memory among members, size is of the largest member. Allocates separate memory for each member.
Value Storage Only one member can hold a value at a time. All members can hold values independently.
Memory Efficiency More efficient, as only the largest member’s size is used. Less efficient, uses memory for all members.
Use Case Ideal for memory-sensitive scenarios such as embedded systems. Ideal when all members need to store values concurrently.
Size Size is equal to the largest member. Size is equal to the sum of the sizes of all members.

Best Practices for Using Unions in C++

  1. You should use unions when there is a need for memory optimization.
  2. Always use an enum or a flag to keep track of the active member in the program.
  3. You should avoid storing non-trivial types in the traditional unions.
  4. You should not read from a member that was not the most recently written.
  5. You must use std::variant in modern C++ wherever it is possible.
  6. Always avoid unions for complex logic and large applications.
  7. You should initialize a union carefully to maintain a consistent state.
  8. Always comment your code properly when unions are used because unions can confuse readers.

Conclusion

Unions are an important way to save memory space in programs. They are powerful data structures that provide type-safety and low-level data handling. But also, unions are used with much more care as they can cause errors or undefined behavior easily. So, by understanding what unions are, how to declare them, how to create a union, assigning and accessing the values, you can write an efficient C++ code using unions.

C++ Unions – FAQs

Q1. What is a Union in C++?

A union in C++ is a special data structure that allows for storing different data types in the same memory location.

Q2. How is a union different from a struct?

A union stores the data types in the same memory location, and a struct stores types in different memory locations.

Q3. Can unions store multiple values at once?

No, a union cannot store multiple values at once, it can only store one value at a time.

Q4. Can unions store non-trivial types like std::string?

Yes, unions can store non-trivial types like std::string in C++11 and later versions.

Q5. What is a nested union in C++?

A nested union in C++ is a union that can contain another union as a member and also allows complex data structures to share memory.

About the Author

Technical Research Analyst - Full Stack Development

Kislay is a Technical Research Analyst and Full Stack Developer with expertise in crafting Mobile applications from inception to deployment. Proficient in Android development, IOS development, HTML, CSS, JavaScript, React, Angular, MySQL, and MongoDB, he’s committed to enhancing user experiences through intuitive websites and advanced mobile applications.

Full Stack Developer Course Banner