Need of Union in C++
Unions in C++ serve several important purposes, making them a valuable feature in the language:
-
Memory Efficiency: Unions allow different data types to share the same memory location, ensuring efficient use of memory. This is particularly useful when you need to represent a single value using different data types.
-
Versatility: Unions provide a flexible way to interpret data in different ways. They enable you to access the same memory location using different data types, allowing for versatile data manipulation and interpretation.
-
Interoperability: Unions facilitate interoperability between different parts of a program or between programs written in different languages. They allow for the creation of data structures that can be shared and understood by multiple components or systems.
-
Low-level Programming: Unions are often used in low-level programming tasks where memory layout and data representation are critical. They provide a mechanism for directly manipulating memory, which is essential in systems programming and embedded systems development.
-
Reducing Redundancy: Unions can help reduce redundancy in data structures by allowing multiple variables to share the same memory space. This can lead to more concise and efficient code, especially in situations where memory usage is a concern.
How to Declare a Union?
We can declare the Union in C++ using the union keyword. Include curly brackets around the member list.
Let's use an example where we store three courses' names, course IDs, and duration. To perform this, we will create the Course union and then declare its three variables, C1, C2, and C3 (each representing one of the three courses), in the main function.
Example
C++
union Course
{
int course ID;
std::string name;
int duration;
};
int main()
{
union Course C1, C2, C3;
return 0;
}
Another way to declare union variables is as follows, where they are declared at the same time as the union is defined.
// C1, C2 and C3 are Course Variables.
union Course
{
int course ID;
std::string name;
int duration;
}C1, C2, C3;
How to access a Union Member?
We can use the dot operator(.) to access the members of the Union in C++.
The syntax to access a Union Member is as follows:
union_name.member_name;
Here's an example to help you understand the dot operator.
union Course
{
int course ID;
char name[20];
int duration;
}C1;
Now accessing the members:
C1.course;
C1.name;
C1.duration;
Example
Here is an example of accessing the members of the Union in C++.
C++
#include<iostream>
using namespace std;
union Ninja
{
int Ninja_id;
char name[20];
float Ninja_Salary;
};
int main()
{
union Ninja N;
cout << "Enter the id of the Ninja: ";
cin >> N.Ninja_id;
cout << "Enter the name of the Ninja: ";
cin >> N.name;
cout << "Enter the salary of the Ninja: ";
cin >> N.Ninja_Salary;
cout << "Ninja's id is: " << N.Ninja_id << endl; // Garbage value will be printed.
cout << "Ninja's name is: " << N.name << endl; // Garbage value will be printed.
cout << "Ninja's salary is: " << N.Ninja_Salary;
return 0;
}
Output:
Enter the id of the Ninja: 1
Enter the name of the Ninja: ABC
Enter the salary of the Ninja: 200000
Ninja's id is: 1212370944
Ninja's name is:
Ninja's salary is: 200000
How to use a Union?
A union will use the same storage location for all its members. The code accessing the union in the previous example has to know which member is in charge of the data. We set N.Ninja_id but then overridden that value with N.name and then N.Ninja_Salary.
Therefore, we must print the value right away before accepting a new data member. This way we can use the data before it gets overwritten.
Example
C++
#include<iostream>
using namespace std;
union Ninja
{
int Ninja_id;
char name[20];
float Ninja_Salary;
};
int main()
{
union Ninja N;
cout << "Enter the id of the Ninja: ";
cin >> N.Ninja_id;
cout << "Ninja's id is: " << N.Ninja_id << endl;
cout << "Enter the name of the Ninja: ";
cin >> N.name;
cout << "Ninja's name is: " << N.name << endl;
cout << "Enter the salary of the Ninja: ";
cin >> N.Ninja_Salary;
cout << "Ninja's salary is: " << N.Ninja_Salary;
return 0;
}
Output:
Enter the id of the Ninja: 1
Ninja's id is: 1
Enter the name of the Ninja: ABC
Ninja's name is: ABC
Enter the salary of the Ninja: 200000
Ninja's salary is: 200000
How to find a Union Size?
Due to the fact that all of the data members of the union in C++ have the same memory location, the data member that is larger than the other member requires more memory space.
Here is an example of finding the Size of the Union in C++.
union {
int Id;
char name[20];
float price;
};
The size of the union mentioned above in memory (1* 20 = 20 byte) will be 20 bytes because the size of the member, name( char = 1 byte), is larger than the size of the other members (Id, price).
Using the code below, where we used the sizeof operator to get the size of the union variable, we can quickly grasp this.
Example
C++
#include<iostream>
using namespace std;
union { // union declaration in global
int Id;
char name[20];
float duration;
}
DSA;
int main() {
cout << "Size of the union variable: " << sizeof(DSA) << " byte";
return 0;
}
Output:
Size of the union variable: 20 byte
Anonymous Union
An anonymous union in C++ is one that is defined without a name. In this, the names of union members are used to access them directly. It suggests that the names stated in an anonymous union must be unique within the context.
Please note that the void main() function contains a declaration(local) of this type of union.
int main()
{
union {
........
........
}
........
}
Example
The programme provided below will help you grasp this.
C++
#include<iostream>
using namespace std;
int main() {
union {
// Declare union in local
int Id;
char name[20];
float hours;
};
cout << "Enter the ID: ";
cin >> Id;
cout << "Enter the Course name: ";
cin >> name;
cout << "Enter the duration in hours: ";
cin >> hours;
cout << "\nThe ID is: " << Id; // It will print garbage value.
cout << "\nThe course name is: " << name; // It will print garbage value.
cout << "\nThe duration in hours is: " << hours; // accurate value print
return 0;
}
Output:
Enter the ID: 1
Enter the Course name: DSA
Enter the duration in hours: 10.5
The ID is: 1093140480
The course name is:
The duration in hours is: 10.5
Restrictions
These additional limitations apply to an anonymous union:
-
It can only have open members; a union with private and protected members produces errors.
-
It must also be specified as static if it is declared in the file or namespace scope.
- Member functions are not permitted.
Unrestricted Union
There are limitations on what kinds of objects can be union members in Standard C++. Unions, for example, are not permitted to include any objects that define non-trivial constructors, destructors, or assignment operators. These constraints are eliminated in C++11. Any special member functions that aren't user-provided are immediately marked as deleted by the compiler if you include such a member in your union.
Unrestricted unions in C++11 can have data members other than POD(Plain-Old-Data) types. Below is an example of code that defines an unrestricted anonymous union of two non-POD types (Python and Java). These two non-POD types contain std::string and std::vector data members; the compiler would create non-trivial custom methods (such as the default constructor) for those two systems.
// Python and Java are non-POD types
struct Python {
std::vector<std::string> algorithms;
// .. more attributes
};
struct Java {
std::string algorithms;
// .. more attributes
};
It's important to note that the online C++ compiler deletes the special methods(such as the default constructor and destructor) when a struct contains a union with a non-POD type.
Here is a simple example of the unrestricted union.
Example
C++
// placement new
#include <new>
// std::string
#include <string>
// assert(...)
#include <cassert>
// For printing purposes
#include <iostream>
class unrestricted_Union
{
typedef std::string str_type;
enum
{
is_cnstr,
is_str
} flag;
union
{
const char *cnstr;
str_type str;
};
public:
unrestricted_Union(const char *content) : flag(is_cnstr)
{
std::cout << "Constructor Called" << std::endl;
cnstr = content;
}
unrestricted_Union(const std::string &content) : flag(is_str)
{
// call the copy constructor of str (placement new)
new (&str) str_type(content);
}
unrestricted_Union(std::string &&content) : flag(is_str)
{
// call the move constructor of str (placement new)
new (&str) str_type(std::move(content));
}
// operator= is implicitly deleted because the compiler can't handle the unrestricted union
const char *c_str() const
{
return (flag == is_cnstr) ? cnstr : str.c_str();
}
bool is_std_string() const
{
std::cout << "Comparison Operator Called for" << std::endl;
return flag == is_str;
}
~unrestricted_Union()
{
// call destructor of str if needed
std::cout << "Destructor Called" << std::endl;
if (flag == is_str)
str.~str_type();
}
};
int main(int, char **)
{
unrestricted_Union f1("Coding Ninjas");
assert(f1.is_std_string() == false);
unrestricted_Union f2(std::string("Code Studio"));
assert(f2.is_std_string() == true);
delete &f1;
return 0;
}
Here, unrestricted_Union is an immutable wrapper around either a std::string or a const char*.
Output
Constructor Called
Comparison Operator Called for
Comparison Operator Called for
Destructor Called
Frequently Asked Questions
What is a union in C++?
A union in C++ is a data structure that allows different data types to be stored in the same memory location. Unlike structures, unions share memory, enabling efficient memory usage.
What is difference between struct and union in C++?
In C++, a struct allocates separate memory for each member, while a union shares memory among its members. This means a union's size is determined by its largest member.
What is union and enum in C++?
A union in C++ is a data structure that allows multiple variables to share the same memory location. An enum is a user-defined data type that consists of a set of named integer constants.
What is union with syntax?
The syntax for declaring a union in C++ is:
union UnionName {
member1;
member2;
// more members if needed
};
In a union, all members share the same memory space, and the size of the union is determined by the size of its largest member.
Conclusion
We have discussed the Union in C++ in detail. When you have a large number of objects but less memory, a union can be helpful for memory management. Every union member has access to the same memory location. As a result, a union in C++ can only have one object from its list of members present at once.
We hope this blog has helped you. We recommend you visit our articles on different topics of C++, such as
If you liked our article, do upvote our article and help other ninjas grow. You can refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and Algorithms, Competitive Programming, System Design, and many more!
To learn more about Data Structures and Algorithms, you can enroll in our DSA in C++ Course.
Happy Reading!!