Please, can any one explain me, how/when to use union with examples?
Thanks in advance.
Printable View
Please, can any one explain me, how/when to use union with examples?
Thanks in advance.
When you want to actually store only one of the given list of variables (any POD type) at any time. C++ Unions Regards.
For example in a MP3 tag (ID3v1) after the year of release you can either store a 30 chars long comment or you store only a 28 chars long comment a terminating zero and the track number. The data structure would look like this:
You can see that in the union you have cCommentTrack for alternative one and the struct for alternative two. The advantage: You don't have to worry about the different data formats when you read it in.Code:struct ID3v1
{
char cTag[3]; // Always "TAG"
char cTitle[30]; // Song title
char cArtist[30]; // Artist name
char cAlbum[30]; // Album name
char cYear[4]; // Year of release
union
{
char cCommentTrack[30]; // Comment with 30 chars
struct
{
char cComment[28]; // Comment with 28 chars
unsigned char nZero; // Terminating zero
unsigned char nTrack; // Track number
};
};
unsigned char nGenre; // Genre
};
Edit: Oops, misread the previous post. Carry on.
Here is a great use for unions:
How do I impose a packet scheme?
Also,
U can use Unions to represent different types that are not related to one another but wanna use them polymorphically.
In places where u cannot use inheritance and where u know the exact types and number of types and the types are in actuality not realated to each other u can use Unions.
For example:
Type contains the current typeCode:struct MyField
{
enum TypeTag { One, Two, Three,
Four, Five } Type;
union
{
FirstType TypeOne;
SecondType TypeTwo;
ThirdType TypeThree;
FourthType TypeFour;
FifthType TypeFive;
};
};
Unions can be used for portability.
For example, it is often useful (for a C program) to pass user data to a callback function.
And the user may want to pass much data. In that case, a void* parameter as context parameter is good.
But, the user may also want to pass just a small integer value, because he does not need much data.
But, there are platforms where sizeof(void*)!=sizeof(int), so the user cannot (if he want to write a portable program) uses static cast to cast the int to void*, and then void* to int back in his callback function.
So, he would need to allocate memory for this integer variable (dynamically, in some cases), and then free the memory when the callback function is no more needed.
That is not very efficient, although it is generally not a real problem, and may introduce memory leaks if the programmer is not very attentive.
That is why, instead of a void* or an integer value, the best, for the library/system developer, is to define an union:
A good example, of that usage, can be found in the Realtime Signal Extensions option of the Single UNIX Specification.Code:union context_val
{
int int_val;
void* pointer_val;
};
The sigval union is passed as parameter to the signal-notification-handling procedure.
And sigval contains these fields:
The user-defined sigevent structure is used to specify how the event signal is raised, and contains a signal number, but also a sigval value.Code:int sival_int Integer signal value.
void *sival_ptr Pointer signal value.
On the other side, the Win32 API, which is not bound to the C language, defines an UINT_PTR type instead. The "layout" of this type is defined by microsoft, and any language which wants to use this type must use a header/module which defines this type apropriately and allow to use its layout in a language-independent manner, although the header/module is language-specific.
OLE's VARIANTs is another example of union usage.
There are more usage of unions, good... and bad...
The terminating null is not required by the ID3v1 tag, just store 29 chars without terminating null. Sorry for being OT.Quote:
Originally Posted by philkr