简体   繁体   中英

Where to use union, class and struct?

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

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 struct s 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 union s 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);

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(ie I need to add methods) I use a class.

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.

There are some areas where I may use a struct over a class :

  • If I want to define an interface type that contains only pure virtual methods. This aligns with the notion that struct defaults to public .
  • Pure data-only types, where there is no behavior attached to the type.
  • Policy or trait types, as a matter a personal preference.

The union is neither a class or a struct . I only used them in C to create discriminated or variant types at a time when memory was a premium. In C++, I don't see much of an advantage in typical applications, but may still be used in embedded or low-memory applications.

Typically structs and unions are used together in C when one is accessing registers. A struct can define each bit and allow for each bit in the register to be set individually. A union will allow all the bits to be changed or accessed at the same time.

Even in C++ one needs a way to setup the hardware and write to the registers of the chip.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM