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类似的效果,并且会自动析构。
5、union总结:
- 对象不知道它们当前持有的值的类型。
- 由于这个原因,您不能有non-trivial的成员,比如std::string。(从c++ 11起, union原则上可以有non-trivial的成员,但是必须实现特殊的成员函数,比如复制构造函数和析构函数,因为只有通过代码逻辑才能知道哪个成员是可用的。)
- 不能从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
作者:严格鸽
标签:p2,p1,struct,show,union,C++,关键字,int From: https://www.cnblogs.com/karinto/p/17252959.html