Where to use union, class and struct?

12,258

Solution 1

My use of class, struct and union is the following:

  • class for objects that have behaviour.
  • struct for passive data.
  • union for very special cases where different data requires to be accessed as different types.

I've read this (except the union point) in the Google C++ Style guide a long time ago and I was following it since then.

Using structs to carry passive data (objects without behaviour attached to the object) have the advantage of default publicness of the members, so they can be accessed without Getters and Setters. If some member data needs to be checked/modified before assign or some member data needs to be computed/modified before be getted, IMHO they need a Setter/Getter pair and the object is a class instead of a struct.

For the union type, I find it useful for some kind of data structures that requires some weird access to the members, or needs some members to be treated as another type in some contexts. For example a 3D vector or a IP address:

union 3DVector
{
    double x, y, z;
    double vector[3];
} v;

// Acess members with name
v.x = 6.0; v.y = 7.0; v.z = 8.0;
// Acess members as a vector
Normalize(v.vector);

union IPAddress
{
    int binary;
    char octet[4];
} ip;

// Acess the binary address
std::cout << std::hex << ip.binary << '\n';
// Print in a human-readable form
std::cout << static_cast<int>(ip.octet[0]) << '.'
          << static_cast<int>(ip.octet[1]) << '.'
          << static_cast<int>(ip.octet[2]) << '.' 
          << static_cast<int>(ip.octet[3]) << '\n';

The above functionality could be achieved overloading operators and conversion operators, but the union approach looks neat for me.

The unions can also be templated and can have constructor/destructor, this could be useful for serialization purposes (not for all kind of objects):

template <typename T> union Serializer
{
    Serializer(const T &o) : object(o) {}
    T object;
    char binary[sizeof(T)];
};

SomePODObject obj; // Only POD objects please!
Serializer s(obj);
SendBuffer(s.binary);

Solution 2

A union and a class or structure are completely different. A union is several things at the same time, say it can be both a character array and an integer, while a class or structure is one and only one thing that encapsulates some logically connected information, as well as optionally some logic for manipulating it. The use cases for unions and the other two are quite different.

I usually use a structure when I only store some data, while if I also need some logic associated with it(i.e. I need to add methods) I use a class.

Solution 3

I never use union. If you end up looking at this, you better try boost variant. The only acceptable situation where we can use this is when we really need to have a deep control over the content, like custom serialization. But I would run out of this in many cases.

Also, structure are used for storing only data. If you need to add any function/method, convert it into a class.

Share:
12,258
Sumit Gera
Author by

Sumit Gera

I am pretty much familiar with HTML and CSS like to spare my time in Web Development. I love programming in C and C++ and blog about almost every new thing I learn. You can check out My Blog Here

Updated on July 24, 2022

Comments

  • Sumit Gera
    Sumit Gera almost 2 years

    The classes and structs have one difference between them (as far as I know), that the struct defaults to public and class defaults to private. And then I came to know that there is a similar kind of data type which is also used in a similar manner, that is union. The union can not be used as a base class in inheritance (i don't know what that means, but I still accept it).

    I wanted to know whether there are some particular instances, where struct/ union/ class, or they can be used interchangeably (except for the cases I enlisted)? Please do tell me if I am wrong somewhere. Regards

  • Sumit Gera
    Sumit Gera over 11 years
    when do you use a union? And how would you support your statement with this "A union is a user-defined data or class type that, at any given time, contains only one object from its list of members (although that object can be an array or a class type)."? I got this from msdn.microsoft.com/en-us/library/5dxy4b7b(v=vs.80).aspx
  • Luchian Grigore
    Luchian Grigore over 11 years
    @IvayloStrandjev that's undefined behavior. The Q is tagged C++, not C.
  • Ivaylo Strandjev
    Ivaylo Strandjev over 11 years
    @LuchianGrigore in fact I use this hack to find endianess on a machine. I am not sure what you mean by the second part of your comment. There is no such thing as class in C and also I try to give my view of when one uses class and when struct in my answer.
  • Luchian Grigore
    Luchian Grigore over 11 years
    I wasn't talking about class/struct (that part is correct), but your use of union. I mentioned C because AFAIK reading another union member than the one last assigned to is allowed in C, but not in C++. Your "hack" is just UB.
  • Ivaylo Strandjev
    Ivaylo Strandjev over 11 years
    @LuchianGrigore seems it works in c++ too I am not sure what UB means
  • Luchian Grigore
    Luchian Grigore over 11 years
    UB is undefined behavior. It means it can appear to work, but anything can happen. It might as well not work. It might crash or format your hard drive.
  • Ivaylo Strandjev
    Ivaylo Strandjev over 11 years
  • Admin
    Admin over 10 years
    Using union for binary serialization is almost always a bad idea for platform-variability and other reasons. To serialize integers portably, use bitwise tricks (easy). To serialize floats, use ldexp and family plus knowledge of the exact float representation you're serializing to/from (painful). To serialize objects, use the serializations for the members.