非受限联合类型
11.1 联合类型在C++中的局限性
过去C++标准规定,联合类型的成员变量类型不能是一个非平凡类型,即下面的代码不能通过编译:
union U { int x1; float x2; std::string x3; };
|
11.2 使用非受限联合类型
在C++11中,允许联合类型的成员可以是除了引用以外的所有类型。如果联合类型中存在非平凡类型,则必须手动提供联合类型的构造和析构函数。
1. 一个可以但不好的例子
下面的代码可以被使用,但是联合类型在声明时一般不能确定使用哪个成员,因此应用场景较少。
例如:
#include <iostream> #include <string> #include <vector>
union U { U() :x3() {} ~U() { x3.~basic_string(); } int x1; float x2; std::string x3; std::vector<int> x4; };
int main() { U u; u.x3 = "hello world"; std::cout << u.x3; }
|
2. 一个更常见的例子
下面的例子使用了placement
new
的技巧(在某个确定的空间直接构造,此前内存是存在的)来初始化构造成员:
#include <iostream> #include <string> #include <vector>
union U { U() {} ~U() {} int x1; float x2; std::string x3; std::vector<int> x4; };
int main() { U u; new(&u.x3) std::string("hello world"); std::cout << u.x3 << std::endl; u.x3.~basic_string(); new(&u.x4) std::vector<int>; u.x4.push_back(58); std::cout << u.x4[0] << std::endl; u.x4.~vector(); return 0; }
|
3. 非受限联合类型对静态变量的支持
与类基本一致
#include <iostream>
union U { static int x1; } int U::x1 = 42;
int main() { std::cout << U::x1 << std::endl; }
|