首页 > 编程语言 >C/C++:union关键字

C/C++:union关键字

时间:2023-03-24 18:12:57浏览次数:36  
标签:p2 p1 struct show union C++ 关键字 int

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

相关文章

  • override关键字表示该函数会覆盖基类中的虚函数
    override关键字表示该函数会覆盖基类中的虚函数,即在派生类中重新实现了基类中的同名虚函数。在C++中,派生类可以重载其父类的虚函数。使用override关键字可以很好地指出该......
  • c++基础
    三法则(RuleofThree)在C++里,它是一个以设计的基本原则而制定的定律。它的要求是,假如类有明显定义下列其中一个成员函数,那么程序员必须写入其他两个成员函数到类内,也就是说......
  • 为什么C++ 中需要运算符重载
    运算符重载的主要目的是为了方便程序员使用自定义类型。在某些情况下,C++的内置类型可能无法满足程序的需要,需要使用自定义类型。在这种情况下,合适的操作符重载可以使自定义......
  • Docker - dockerfile as 关键字
    在Dockerfile中使用AS(或as)关键字可以创建一个多阶段构建(multi-stagebuild)。多阶段构建是一种将应用程序的构建过程分解为多个阶段(stage)的技术,每个阶段使用不同的基础......
  • 第6章 C++语言新特性111417专题一
    类型推导:auto/decltype语法:auto变量名称=值;(从值推导)​ decltype(表达式)变量名称[=值];(从表达式推导)功能:自动推导出变量名称的类型。案例:#include<iostream>us......
  • caffe中多个cpp共享一个变量 c++类中的静态变量
    caffe中需要整个共享变量,就是从bias过来的tensor转图片,然后后面目标检测第一阶段查看定位效果,把目标框画在图上就需要一开始的图片。实验1:这个可以在prototxt增加一个top......
  • C++ this 指针
    在C++中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。友元函数没有 this 指......
  • C++ 标准库 sort() / stable_sort() / partial_sort() 对比
    C++STL标准库中提供了多个用于排序的Sort函数,常用的包括有sort()/stable_sort()/partial_sort(),具体的函数用法如下表所示:函数用法std::sort(first,last)......
  • what's the difference between const and constexpr in C++?
    BothconstandconstexprareusedtodefineconstantsinC++,buttheyhavedifferentmeaningsandusecases.constisusedtodeclareavariableasconstant,......
  • Loops in C++
    #include<iostream>usingnamespacestd;intmain(){intv[]={0,1,2,3,4};for(autox:v){cout<<x<<endl;}for(autoy:......