|  | Why union cannot have member having user defined constructor |  | |
| | | ashwin |  |
| Posted: Fri Aug 22, 2008 6:50 am Post subject: Why union cannot have member having user defined constructor |  |
In the below code, "un" cannot be created as it has "Obj" member, which has user defined constructor.
#include<iostream> using namespace std;
class A { public: //union 'Union' : member 'iObj' has user-defined constructor or //non-trivial default constructor ?? A(): i(2) { cout<<"A::A()"<<endl; } private: int i; };
union Union { int Val; A Obj; };
int main() { Union un;
cout<<sizeof(un)<<endl; return 0; }
Why this restriction ?
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Ulrich Eckhardt |  |
| Posted: Fri Aug 22, 2008 12:55 pm Post subject: Re: Why union cannot have member having user defined constru |  |
| |  | |
ashwin wrote:
| Quote: | In the below code, "un" cannot be created as it has "Obj" member, which has user defined constructor. [...] Why this restriction ?
|
All members of a union live in the same memory. Constructing multiple objects on that memory doesn't work, since each of them would overwrite the constructor changes of the other. This leaves the option of only constructing one of them, but the union doesn't know which one (there are alternative variant classes which do), just as it doesn't know which one to destroy.
Try running this code and examine the content of the two objects in a debugger. You should see that constructing one damages the other and vice versa. Destroying the last created one will probably work still, but destroying the other will surely fail.
// reserve memory size_t max_size = max<size_t>( sizeof (vector<int>), sizeof (string)); char memory[max_size]; // create objects with placement new vector<int>* pv = new (memory) vector<int>; string* ps = new (memory) string;
Uli
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Guest |  |
| Posted: Fri Aug 22, 2008 12:56 pm Post subject: Re: Why union cannot have member having user defined constru |  |
| |  | |
On Aug 21, 11:50 pm, ashwin <ashwind...@gmail.com> wrote:
| Quote: | In the below code, "un" cannot be created as it has "Obj" member, which has user defined constructor. [snip] Why this restriction ?
|
int main() { struct A { A() : x(1) {} int x; }; struct B { B() : x(2) {} int x; }; union C { A a; B b; }; C c; return c.b.x; }
What would you like this to return? 1? 2? Unspecified? Undefined?
C++ generally has strict rules governing the lifetime of objects. An obect exists as soon as the constructor exits until the destructor. It doesn't mesh well when you start calling multiple constructors on the same memory location, or by not calling a constructor at all for an object of a type which has a constructor. It doesn't mix with the C++ basic idioms well to be able to access an object without its constructor setting up its state.
Now, this isn't to say you can't do this. It's just that C++ tries to make it somewhat hard to shoot yourself in the foot if at all possible. This is one of those cases where the language rules are trying to prevent you from shooting yourself in the foot.
If you REALLY want to do this, you can. You can explicitly allocate a piece of memory, and reinterpret_cast it back and forth. You can control exactly when the constructor of a type is called with placement new, and you can explicitly call a destructor as well. You probably do not want to be doing these things.
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Nicola Musatti |  |
| Posted: Fri Aug 22, 2008 1:01 pm Post subject: Re: Why union cannot have member having user defined constru |  |
On Aug 22, 8:50 am, ashwin <ashwind...@gmail.com> wrote:
| Quote: | In the below code, "un" cannot be created as it has "Obj" member, which has user defined constructor.
#include<iostream using namespace std;
class A { public: A(): i(2) { cout<<"A::A()"<<endl; } private: int i; };
union Union { int Val; A Obj; };
int main() { Union un; cout<<sizeof(un)<<endl; }
Why this restriction ?
|
suppose you do:
un.Val = 42; A a = un.Obj;
un.Obj's constructor never ran, so a is assigned the value of an uninitialized object.
Cheers, Nicola Musatti
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Pete Becker |  |
| Posted: Fri Aug 22, 2008 1:02 pm Post subject: Re: Why union cannot have member having user defined constru |  |
On 2008-08-21 20:50:40 -0400, ashwin <ashwindows@gmail.com> said:
| Quote: | In the below code, "un" cannot be created as it has "Obj" member, which has user defined constructor.
[snip]
Why this restriction ?
|
Because members of unions are default-initialized. If you have a type that needs some other form of initialization it won't get properly initialized inside a union.
This has been changed for C++0x, where the rule will be that by default members of a union will not be initialized.
-- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference (www.petebecker.com/tr1book)
[ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | peter koch larsen |  |
| Posted: Fri Aug 22, 2008 1:04 pm Post subject: Re: Why union cannot have member having user defined constru |  |
| |  | |
On 22 Aug., 08:50, ashwin <ashwind...@gmail.com> wrote:
| Quote: | In the below code, "un" cannot be created as it has "Obj" member, which has user defined constructor.
#include<iostream using namespace std;
class A { public: //union 'Union' : member 'iObj' has user-defined constructor or //non-trivial default constructor ?? A(): i(2) { cout<<"A::A()"<<endl; } private: int i;
};
union Union { int Val; A Obj;
};
int main() { Union un;
cout<<sizeof(un)<<endl; return 0;
}
Why this restriction ?
|
How would you implement it? Every object constructed must be deconstructed, and how would you know what type is currently in the union? While it is possible to implement, it would probably change to much code for compatibility reasons. You could either use a struct or look at boosts solution for unions: while the first is a hack, the second solution gives you all the advantages of a C union and adds typesafety.
/Peter
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Martin Bonner |  |
| Posted: Fri Aug 22, 2008 2:28 pm Post subject: Re: Why union cannot have member having user defined constru |  |
| |  | |
On Aug 22, 7:50 am, ashwin <ashwind...@gmail.com> wrote:
| Quote: | In the below code, "un" cannot be created as it has "Obj" member, which has user defined constructor.
#include<iostream using namespace std;
class A { public: //union 'Union' : member 'iObj' has user-defined constructor or //non-trivial default constructor ?? A(): d(2.0) { cout<<"A::A()"<<endl; } private: double d; |
// Changed member to double for exposition.
| Quote: | };
union Union { int Val; A Obj;
};
int main() { Union un;
|
At this point, does un contain a int (Val) or an A (containg a double)?
In fact, it contains *neither* (so neither can be constructed). You have to assign to either un.Val or un.Obj before you are allowed to use the member. Furthermore, you are not allowed to use a member unless the most recent assignment was to that member (*).
| Quote: | cout<<sizeof(un)<<endl; return 0;
}
Why this restriction ? See above |
(*) Yes, yes, I know. There are exceptions concerning POD-structs with common initial sequences of members.
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
|
|