C++ Programming/Unions
The union keyword is used to define a union type.
- Syntax
union union-name
{
public-members-list;
private:
private-members-list;
} object-list;
Union is similar to struct
(more than class
), unions differ in the aspect that the fields of a union
share the same position in memory and are by default public
rather than private
. The size of the union
is the size of its largest field (or larger if alignment so requires, for example on a SPARC machine a union
contains a double
and a char [17]
so its size is likely to be 24 because it needs 64-bit alignment). Unions cannot have a destructor
.
What is the point of this? Unions provide multiple ways of viewing the same memory location, allowing for more efficient use of memory. Most of the uses of unions are covered by object-oriented features of C++, so it is more common in C. However, sometimes it is convenient to avoid the formalities of object-oriented programming when performance is important or when one knows that the item in question will not be extended.
union Data {
int i;
char c;
};
Writing to Different Bytes
editUnions are very useful for low-level programming tasks that involve writing to the same memory area but at different portions of the allocated memory space, for instance:
union item
{
// The item is 16-bits
short theItem;
// In little-endian lo accesses the low 8-bits -
// hi, the upper 8-bits
struct { char lo; char hi; } portions;
};
item tItem;
tItem.theItem = 0xBEAD;
tItem.portions.lo = 0xEF; // The item now equals 0xBEEF
Using this union we can modify the low-order or high-order bytes of theItem without disturbing any other bytes.
Example in Practice: SDL Events
editOne real-life example of unions is the event system of SDL, a graphics library in C. In graphical programming, an event is an action triggered by the user, such as a mouse move or keyboard press. One of the SDL's responsibilities is to handle events and provide a mechanism for the programmer to listen for and react to them.
// primary event structure in SDL
typedef union
{
Uint8 type;
SDL_ActiveEvent active;
SDL_KeyboardEvent key;
SDL_MouseMotionEvent motion;
SDL_MouseButtonEvent button;
SDL_JoyAxisEvent jaxis;
SDL_JoyBallEvent jball;
SDL_JoyHatEvent jhat;
SDL_JoyButtonEvent jbutton;
SDL_ResizeEvent resize;
SDL_ExposeEvent expose;
SDL_QuitEvent quit;
SDL_UserEvent user;
SDL_SysWMEvent syswm;
} SDL_Event;
Each of the types other than Uint8 (an 8-bit unsigned
integer) is a struct with details for that particular event.
// SDL_MouseButtonEvent
typedef struct
{
Uint8 type;
Uint8 button;
Uint8 state;
Uint16 x, y;
} SDL_MouseButtonEvent;
When the programmer receives an event from SDL, he first checks the type value. This tells him what kind of an event it is. Based on this value, he either ignores the event or gets more information by getting the appropriate part of the union.
For example, if the programmer received an event in SDL_Event ev, he could react to mouse clicks with the following code.
if (ev.type == SDL_MOUSEBUTTONUP && ev.button.button == SDL_BUTTON_RIGHT)
{
cout << "You have right-clicked at coordinates (" << ev.button.x << ", "
<< ev.button.y << ")." << endl;
}
While identical functionality can be provided with a struct rather than a union, the union is far more space efficient; the struct would use memory for each of the different event types, whereas the union only uses memory for one. As only one entry has meaning per instance, it is reasonable to use a union in this case.
This scheme could also be constructed with polymorphism and inheritance features of object-oriented C++, however the setup would be involved and less efficient than this one. Use of unions loses type safety, however it gains in performance.
this
editThe this keyword is a implicitly created pointer that is only accessible within nonstatic member functions of a union (or a struct or class ) and points to the object for which the member function is called. The this pointer is not available in static member functions. This will be restated again on when introducing unions a more in depth analysis is provided in the Section about classes.