1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
Standard (bf(C)-type) unions can only have fields of basic types, like tt(int,
double) and pointers. bf(C++) extends the bf(C)-type union concept by offering
hi(unrestricted union)em(unrestricted unions).
Unrestricted unions also allow data fields of types for which non-trivial copy
constructors were defined. Such data fields commonly are of class-types. Here
is an example of such an unrestricted union:
verb( union Union
{
int u_int;
std::string u_string;
};)
One of its fields is defined as a tt(std::string) (having a constructor),
turning this union into an em(unrestricted) union. As an unrestricted union
defines at least one field of a type having a constructor the question becomes
how these unions can be constructed and destroyed.
The destructor of a union consisting of, e.g. a tt(std::string) and an
tt(int) should of course not call the tt(string)'s destructor if the
union's last (or only) use referred to its tt(int) field. Likewise, when
the tt(std::string) field is used, and processing switches from the
tt(std::string) to the tt(int) field, tt(std::string)'s destructor
should be called before any assignment to the tt(int) field takes place.
The compiler does not solve the issue for us, and in fact does not at all
implement default constructors or destructors for unrestricted unions. If we
try to define an unrestricted union like the one shown above, an error message
is issued. E.g.,
verb( error: use of deleted function 'Union::Union()'
error: 'Union::Union()' is implicitly deleted because the default
definition would be ill-formed:
error: union member 'Union::u_string' with non-trivial
'std::basic_string<...>::basic_string() ...')
|