In C++11 and later, you can have class-type members with non-trivial constructors/destructors, but you must explicitly construct/destruct them using placement new or similar techniques — they are not automatically managed.
#include <iostream>
#include <string>
class Screen {
public:
Screen();
~Screen();
};
union MyUnion {
Screen s;
std::string str; // non-trivial member
static int i;
// Constructor
// --> Placement new
MyUnion() {
new (&str) std::string("hello");
}
// Deconstructor
// --> Explicit destructor
~MyUnion() {
// Use the actual class name instead of the typedef.
str.~basic_string<char, std::char_traits<char>, std::allocator<char>>();
}
};
int MyUnion::i = 3;
int main() {
MyUnion u;
u.str = "123";
std::cout << u.str << std::endl;
std::cout << MyUnion::i << std::endl;
return 0;
}
class A {
public:
union X{
int i;
void foo(){ }
};
};
class B {
public:
union {
int j;
// void bar(){ }; // Error: anonymous union cannot have member function;
private:
// int x; // Error: anonymous union cannot have private members
protected:
// int y; // Error: anonymous union cannot have protected members
} q;
};
class C {
public:
union {
int k;
};
};
// An anonymous union defined in global scope must be declared as static
static union {
int x;
};
int main() {
A::X u;
u.i = 42; // Access member 'i' directly as part of object 'a'
B b;
b.q.j = 1;
C c;
c.k = 3;
return 0;
}