C + + Federation Union Usage example detailed _c language

Source: Internet
Author: User
Tags anonymous

This article describes the C + + Federation union usage. Share to everyone for your reference. Specifically as follows:

We should follow the Convention in C to use Union, which is the point I want to give in this article. Although C + + allows us to expand some new things in, but I suggest you do not do so, after reading this article, I think you probably think so.

c because there is no concept of class, all types can actually be regarded as a combination of basic types, so it is a natural thing to include struct in the Union, and after C + +, since it is generally accepted that struct in C + + is basically equivalent to class, So is there a class member in the union? Let's take a look at the following code:

struct testunion
{  testunion () {}
};

typedef Union
{  testunion obj;
} UT;

int main (void)
{return  0;
}      

To compile this program, we will be told:
  Error c2620:union ' __unnamed ': Member ' obj ' has user-defined constructor or non-trivial default constructor

And if you remove the constructor that did nothing, then everything is OK.

Why does the compiler not allow our union members to have constructors? I cannot find a more authoritative explanation on this question, and my explanation is:

If the C + + standard allows our union to have constructors, do you want to perform this constructor when allocating space? If the answer is yes, then if the TestUnion constructor contains some memory allocation operations, or any other modification to the entire application state, then, if I were to use obj in the future, things might be more reasonable, but what if I didn't use obj as a member? The modification of the system state caused by the introduction of obj is obviously unreasonable; conversely, if the answer is no, Then once we have selected obj to do the operation, then all information is not initialized (if it is normal struct, no problem, but, if there is a virtual function?). Further, suppose that our Union is now not only a testunion obj, but also a TestUnion2 obj2, both of which have constructors, and have performed some memory allocations in the constructor (and even many other things), then if obj is constructed first, After constructing obj2, the results of execution can almost certainly cause memory leaks.

In view of the many problems (and perhaps more), when constructing union, the compiler is only responsible for allocating space, not for performing additional initialization work, and for simplifying the work, we receive the above error if we provide a constructor.

Likewise, the destructor/copy constructor/assignment operator cannot be added except for the constructor function.

In addition, if our class contains any virtual functions, we will receive the following error message at compile time:
Error c2621:union ' __unnamed ': Member ' obj ' has copy constructor

So, to eliminate the idea of a class member variable that contains constructors/destructors/copy constructors/assignment operators/virtual functions in the Union, honestly use your C-style struct!
However, defining ordinary member functions is OK, because this does not make class and C-style struct have any essential difference, you can fully interpret such class as a C-style struct + N global functions.

Now, let's look at the difference in how the inner Union is included in the class. Take a look at the following program, and note that the Reading program prompts:

Class TestUnion
{  Union dataunion  {    dataunion (const char*);    Dataunion (long);    Const char* Ch_;    Long l_;  }  Data_;

Public:  testunion (const char* CH);  TestUnion (long L);
};

Testunion::testunion (const char* CH): Data_ (CH)//If you want to use initialzing list to initiate a                                nested-union me Mber, the Union must not be anonymous and                              must have a constructor.
{}

Testunion::testunion (Long L): Data_ (L)
{}

testunion::D ataunion::D ataunion (const char* CH): Ch_ (ch)
{

testunion::D ataunion::D ataunion (Long L): L_ (L)
{}

int main (void) {return  0;
}                    

As the above program shows, the union in C + + can also contain constructors, but, although it is supported by the language but it is a poor programming habit, I do not intend to explain the above program too much. I also recommend the following programming style:

Class TestUnion
{  Union dataunion  {    const char* ch_;    Long l_;  }  Data_;
Public:  testunion (const char* CH);  TestUnion (long L);
};

Testunion::testunion (const char* ch)
{  data_.ch_ = ch;
}

Testunion::testunion (long L)
{  data_.l_ = l;
}

int main (void)
{return  0;
}                      

It's completely C-style.

So, accept this conclusion:

Follow the Convention in C to use union and try not to attempt to use any C + + add-on features.

Union is a good thing, union is a struct, in which all the members share a piece of memory, size by the largest member of the decision, access to members will be the type of member to parse the memory; In GameDev, Union can make a difference in these respects:

1. Change the name:

struct Rename
{public
  :
    Union
    {
      struct 
      {
        float x,y,z,w;
      };
      struct
      {
        float vec[4];
      }
    ;
};

In this way, we can either access the variable according to the specific meaning or loop like an array;

2. Compression:

struct Compression
{public
 :
   bool operator== (const compression& arg) Const {return value = = Arg.value;}
   Union
   {
     struct 
     {
       char a,b,c,d,e,f,g;
     };
     struct
     {
       Long value;}
     ;}
   ;

So for the centralized treatment of the situation, such as = =, will greatly improve efficiency, as in 64-bit machine, as long as once, or the transmission of data, compression decompression is very convenient;

3. Danger:

Anonymous union usage, not standard, so on the compiler to confirm the ==> compiler is not good;
The size of the data on the different machine operating systems is not the same, so it is dangerous to use Union, especially when it is transplanted.
But if the system, compiler, is the same, it is OK to use union in the right place.

Union (Union) does not see much in C/s + +, but in some places where memory requirements are particularly stringent, unions are frequent, so what exactly is the union, how to use, and what needs attention? On these questions, I try to do some simple answer, there must be some improper place, welcome to point out!

1. What is Union?

"Union" is a special class and a data structure of a constructed type. There are many different types of data that can be defined within a "union". In a variable that is described as the "Union" type, it is permissible to mount any of the data defined by the Union, which shares the same memory, and has achieved space-saving purposes (and a space-saving type: a bit field). This is a very special place, and it is also a feature of union. In addition, as with struct, federated default access is public, and also has member functions.

2. What is the difference between union and structure?

There are some similarities between "union" and "structure". But the two are fundamentally different. In the structure, each member has its own memory space, and the total length of a structure variable is the sum of the length of each member (except for the empty structure, regardless of the boundary adjustment). In union, each member shares a memory space, and the length of a union variable equals the longest length of each member. It should be explained that the so-called sharing here does not mean that multiple members are loaded into a union variable at the same time, but that the union variable can be assigned to any member value, but only one value can be assigned at a time, and the new value is flushed to the old value.

Here is an example to add to the understanding of the deep Union.

Example 4:

#include <stdio.h>
void Main ()
{
  union number
  {* * * defines a joint/
   int i;
   struct
   {/* defines a struct in the union *
    /char A;
    char second;
   } Half;
  } num;
  num.i=0x4241; /* Union member Assignment
  /printf ("%c%c\n", Num.half.first, Num.half.second);
  Num.half.first= ' a '; /* The struct member assignment
  /num.half.second= ' B ';
  printf ("%x\n", NUM.I);
  GetChar ();
}

The output results are:

Ab
6261

It can be seen from the above example that when I assign a value to I, its low eight bits are the values of first and second; When the first and second characters are assigned, the ASCII code of the two characters will also be the lower eight bits of I and eight bits higher.

3, how to define?

For example:

Union test
{
  test () {}
  int office;
  Char teacher[5];

Defines a union type named Test that contains two members, one integer, member office, and one character array, with the array named teacher. After a joint definition, a joint variable description, described as a variable of type test, can hold an integer office or an array of character teacher.

4, how to explain?

The description of the Union variable has three forms: first, the definition, the definition, the description and the direct description.

Take the test type as an example, as follows:
1)

Union test
{
  int office;
  Char teacher[5]; 
Union Test A,b; /* Description A,B is test type * *

2)

Union test
{
  int office;
  Char teacher[5];
} A,b;

3)

Union 
{
  int office;
  Char teacher[5];
} A,b;

The a,b variables described are all test types. The length of the a,b variable should be equal to the longest length in the member of Test, which is equal to the length of the teacher array, a total of 5 bytes. The a,b variable, when given an integer value, uses only 4 bytes, while assigning a character array can be 5 bytes.

5, how to use?

The assignment to a union variable can only be performed on a member of a variable. A member of a union variable is represented as:
Union variable name. Member Name
For example, after a is described as a variable of type test, you can use A.class, A.office
It is not allowed to assign values or other operations to only union variable masterpieces, nor does it allow initialization of union variables, and assignments can only be performed in programs.
It is also emphasized that a union variable can be assigned only one member value at a time. In other words, the value of a union variable is the value of a member of the Union change.

6. Anonymous Union

The anonymous union only notifies the compiler that its member variables share an address, and the variable itself is directly referenced without using the usual dot operator syntax.
For example:

#include <iostream>
void Main ()
{
  union{ 
  int test;
  char c; 
  }; 
  test=5;
  C= ' a ';
  std::cout<<i<< "" <<c;
}

As you can see, the joint component is referred to as the ordinary local variable declared, which is actually the way to use these variables for the program. In addition, although defined in a joint statement, They have the same scope level as any other local variable that is faster than the same program. This means that the names of the members within the anonymous Union cannot conflict with other constant flags within the same scope.
There are also the following restrictions on anonymous unions:
Because anonymous unions do not use the dot operator, the elements contained within an anonymous union must be data, no member functions are allowed, and private or protected members cannot be included. Also, the Global Anonymous federation must be static (static), otherwise it must be placed in the anonymous namespace.

7. Some points to discuss:

1 Is there anything in the joint that can't be stored?

We know that the combination of things in the shared memory, so static, reference can not be used, because they can not share the memory.

2 can classes be put together?

Let's take a look at an example:

Class Test
{public
  :
  Test ():d ata (0) {}
  private:
  int data;
};
typedef Union _TEST
{
  test test; 
} UI; 

Compilation pass But, why?
Because the union is not allowed to hold classes with constructors, destructors, copy operators, and so on, because they share memory, the compiler cannot guarantee that these objects are not corrupted, and can not guarantee that the function is called when leaving.

3) is also an anonymous cause of trouble??
Let's look at the next piece of code:

Class Test
{public
  :
  Test (const char* p);
  Test (int in);
  Const operator char* () const {return
  data.ch;}
  operator long () const {return data.l;}
  Private:
  enum type {Int, String};
  Union 
  {
   const char* ch;
   int i;
  } datatype;
  Type stype;
  Test (test&);
  test& operator= (const test&);
Test::test (const char *p): Stype
(String), datatype.ch (p) {}
test::test (int in): stype (int), DATATYPE.L (i) {
}

Do you see anything wrong? Oh, compile pass however. Why, then? Is there a problem with datatype.ch (p) and DATATYPE.L (i)?
Haha, what's the problem? Let's take a look at what happens when you construct the test object. When the test object is created, it is natural to invoke its corresponding constructor, which, of course, calls its member's constructor, so it calls the constructor of the datatype member, but he has no constructor to call, so the
Wrong.
Note that this is not an anonymous union! Because it's followed by a data!.

4 How to effectively prevent access errors?

Using a union saves memory space, but there is a risk that you get the value of the current object through an inappropriate data member! For example, the above ch, I interleaved access.

To prevent such errors, we must define an additional object to track what is currently being stored in the union, which we call the additional object: the discriminant of Union.

A better experience is to provide a set of access functions for all union data types when dealing with union objects that are members of a class.

I hope this article will help you with the C + + program design.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.