Strange elements of a class of behavior within the union

Hi, I need to know the reasons for the following code.

void main() { class test { public: test(){} int k; }; class test1 { public: test1(){} int k; }; union Test { test t1; test1 t2; }; } 

For the code above, it gives the error " error C2620: union 'Test': member 't1' has a user-defined constructor or non-trivial default constructor "

 class test { public: //test(){} int k; }; class test1 { public: //test()1{}; int k; }; union Test { test t1; test1 t2; }; 

For the above, no errors.

I wanted to know the reasons.

Thank you at Advance. :)

+3
source share
3 answers

According to the C ++ standard (ยง9.5.1, also cited in other answers):

A union can have member functions (including constructors and destructors), but not virtual functions. The union should not have base classes. A union should not be used as a base class. A class object with a nontrivial constructor, a nontrivial copy constructor, a nontrivial destructor, or a nontrivial copy assignment operator cannot be a member of a union and cannot be an array of such objects. If the union contains a static data member or a member of a reference type, the program is poorly formed.

I first contacted the Wikipedia article on POD types , which states:

The POD type in C ++ is defined as a scalar type or POD class. The POD class does not have a user-defined copy assignment operator, no user-defined destructor, and no non-static data members that are not PODs per se. In addition, the POD class must be an aggregate, that is, it does not have constructors declared by the user, does not have any private or protected non-static data, databases without virtual functions. The standard includes instructions on how POD should behave in C ++.

and

In certain contexts, C ++ only allows the use of POD types. For example, a union in C ++ cannot contain a class with virtual functions or non-trivial constructors or destructors . This restriction is imposed because the compiler cannot know which constructor or destructor should be called to join.

The first sentence of the second paragraph may make you think that C ++ only allows POD types to be part of a union. This is not entirely true, since it allows a class with private members to be part of a union:

 #include <iostream> using namespace std; class test1 { int i; }; class test2 { int i; }; union test { test1 t1; test2 t2; }; int main() { cout << __is_pod(test1) << endl; cout << __is_pod(test2) << endl; cout << __is_pod(test) << endl; return 0; } 

The above program with MSVC ++ produces:

 0 0 1 
+15
source

The C ++ standard sets certain restrictions on the types of data that can be placed inside a union. In 9.5.1, the standard states:

An object is a class with a nontrivial constructor, a nontrivial instance constructor, a nontrivial destructor, or a nontrivial copy assignment operator cannot be a member of a union and cannot an array of such objects. If the union contains a static data element or a member of a reference type, the program is poorly formed.

Thus, your program does not work because you explicitly define the constructor, and therefore your object violates the non-trivial constraint of the constructor.

+5
source

In C ++, associations cannot contain classes with (non-trivial) constructors or destructors. This is because the compiler is not able to tell which constructor or destructor to use when the union instance is created or destroyed.

+2
source

All Articles