1、union内存分布:
union U {
int x;
float y;
};
int main()
{
U u;
u.x = 123;
show(u.x);
u.y = 16.256;
show(u.x, u.y); //union两个变量共用一块内存, u.x的输出不正确
return 0;
}
2、union短字符串优化
struct short_str {
union { //匿名union
unsigned long long hs;
char s[8];
};
};
int main()
{
short_str s;
memcpy(s.s, "12345", 6);
show(s.s, s.hs); //通过传入s.s, 输出s.hs, 可以快速地获得短字符串的哈希值
return 0;
}
3、union取别名简化操作
在二维问题中,我们定义了如下line和point结构体,但访问具体数据就需要操作name.p1.x,较为麻烦。
struct point {
int x, y;
};
struct line {
point p1, p2;
};
同样可以通过union的内存分布特性简化这一操作步骤,将struct point p1, p2和int arr[4]使用union联合起来。
struct point {
int x, y;
};
struct line {
union {
struct {
point p1, p2;
};
int arr[4];
};
};
int main()
{
line L = { 123, 456, 789, 1020 };
show(L.p1.x, L.p1.y, L.p2.x, L.p2.y);
for (int i = 0; i < 4; i++) { L.arr[i] = i + 567; }
show(L.p1.x, L.p1.y, L.p2.x, L.p2.y);
return 0;
}
4、union实现简单动态类型
struct var {
union {
int iv;
double dv;
char *sv; //char* sv
};
var(const int& v) : iv{ v } {};
var(const double& v) : dv{ v } {};
var(const char* s) {
int len = strlen(s);
sv = new char[len + 1];
memcpy(sv, s, len + 1);
}
};
int main()
{
var x = 1234;
show(x.iv);
x = 3.14;
show(x.iv, x.dv);
x = "hello~~~";
show(x.iv, x.dv, x.sv);
return 0;
}
由上例,我们并没有detele掉释放new出的内存,为了避免内存泄漏,我们希望union能做到内存的自动释放,但原生union又不能做到自动析构。
C++17中引入一个variant ,它可以实现和union类似的效果,并且会自动析构。
源代码:
#include <iostream>
using namespace std;
void show() { cout << endl; }
template<typename T, typename... Types>
void show(const T& firstArg, const Types&... args) {
cout << firstArg << " ";
show(args...);
}
union U {
int x;
float y;
};
struct short_str {
union { //匿名union
unsigned long long hs;
char s[8];
};
};
struct point {
int x, y;
};
struct line {
union {
struct {
point p1, p2;
};
int arr[4];
};
};
struct var {
union {
int iv;
double dv;
char *sv; //char* sv
};
var(const int& v) : iv{ v } {};
var(const double& v) : dv{ v } {};
var(const char* s) {
int len = strlen(s);
sv = new char[len + 1];
memcpy(sv, s, len + 1);
}
};
int main()
{
U u;
u.x = 123;
show(u.x);
u.y = 16.256;
show(u.x, u.y); //union两个变量共用一块内存, u.x的输出不正确
short_str s;
memcpy(s.s, "12345", 6);
show(s.s, s.hs); //通过传入s.s, 输出s.hs, 可以快速地获得短字符串的哈希值
line L = { 123, 456, 789, 1020 };
show(L.p1.x, L.p1.y, L.p2.x, L.p2.y);
for (int i = 0; i < 4; i++) { L.arr[i] = i + 567; }
show(L.p1.x, L.p1.y, L.p2.x, L.p2.y);
var x = 1234;
show(x.iv);
x = 3.14;
show(x.iv, x.dv);
x = "hello~~~";
show(x.iv, x.dv, x.sv);
return 0;
}
执行结果:
123 1099041866 16.256 12345 14757170307495309873 123 456 789 1020 567 568 569 570 1234 1374389535 3.14 16716512 -9.25596e+61 hello~~~
原文:https://zhuanlan.zhihu.com/p/595288133
作者:严格鸽