[C++]现代C++语言核心特性解析 Chapter 11

非受限联合类型(C++11)

1 联合类型在C++中的局限性

过去的C++标准规定,联合类型的成员变量的类型不能是一个非平凡类型,也就是说它的成员类型不能有自定义构造函数

1
2
3
4
5
6
union U
{
int x1;
float x2;
std::string x3;
};

上面的代码是无法通过编译的,因为x3存在自定义的构造函数,所以它是一个非平凡类型。

2 使用非受限联合类型

在C++11中联合类型的成员可以是除了引用类型外的所有类型。

在C++11中如果有联合类型中存在非平凡类型,那么这个联合类型的特殊成员函数将被隐式删除,也就是说我们必须自己至少提供联合类型的构造和析构函数。

推荐的做法是让联合类型的构造和析构函数为空,也就是什么也不做,并且将其成员的构造和析构函数放在需要使用联合类型的地方。

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
#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"); // placement new技巧
std::cout << u.x3 << std::endl;
u.x3.~basic_string();

new(&u.x4) std::vector<int>; // placement new技巧
u.x4.push_back(58);
std::cout << u.x4[0] << std::endl;
u.x4.~vector();
}

联合类型的静态成员不属于联合类型的任何对象,所以并不是对象构造时被定义的,不能在联合类型内部初始化。实际上这一点和类的静态成员变量是一样的,当然了,它的初始化方法也和类的静态成员变量相同:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
union U
{
static int x1;
};
int U::x1 = 42;

int main()
{
std::cout << U::x1 << std::endl;
}

[C++]现代C++语言核心特性解析 Chapter 11
https://erlsrnby04.github.io/2024/11/01/C-现代C-语言核心特性解析-Chapter-11/
作者
ErlsrnBy04
发布于
2024年11月1日
许可协议