《Hello C++》4.3 共用体

《Hello C++》4.3 共用体
0x3ff18a共用体(union)是一种特殊的数据结构,它允许不同的数据成员共享同一块内存区域。这意味着,尽管共用体可以包含多个不同类型的成员,但在任何一个时刻,它只能存储其中一个成员的值。这种设计使得共用体在特定场景下非常有用,尤其是在需要考虑内存节省的情况下。
共用体的定义方式与结构体(struct)相似,但需要把关键字换成 union。例如,你可以定义一个包含整型、字符型和浮点型成员的共用体。
1 |
|
然而,与结构体所有成员独立占用内存空间不同,共用体的所有成员都从相同的内存地址开始存储。因此,一个共用体变量所占用的总内存大小,由其最长的成员决定。例如,如果一个共用体包含一个 int(通常占 4 字节)和一个 double(通常占 8 字节),那么该共用体的大小就是 8 字节。这种内存共享机制也带来了一个关键特性:当你给一个成员赋值后,再给另一个成员赋值,就会覆盖之前的值,因为它们共享同一块内存。所以,在某一时刻,只有最后一次被赋值的成员是有效的。
1 | // 存储整数 |
由于共用体的这种特性,在使用时有几点需要特别注意。你不能直接对共用体中定义的变量名进行赋值或初始化,也不能用它作为函数参数或返回值,而只能通过其成员来访问数据。同时,共用体变量的地址和它各个成员的地址都是相同的。在 C++ 中,共用体可以像类一样拥有成员函数(如构造函数),但不能有虚函数、静态数据成员或引用成员,也不能作为基类使用(面向对象及类的知识我们会在第七章类与对象中讲到)。此外,如果共用体的成员是自定义类型(如某个类的对象),那么该类不能有构造函数、析构函数、重载的赋值运算符或虚函数。
共用体一个典型的应用场景是当某个数据项可能具有多种类型,但在一段时间内只会使用其中一种类型时,可以用来节省内存。例如,在一个商品管理结构中,有些商品的 ID 是整数,有些则是字符串,就可以使用共用体来存储 ID。共用体也常用于低级编程,如操作系统数据结构、硬件寄存器访问或需要直接处理数据字节的场景(例如类型转换或分离高低字节)。还有一种特殊的匿名共用体(anonymous union),它没有名称,其成员可以直接被外层结构体或类的成员访问,使得代码更加简洁。
1 |
|
在实际编程中,为了确保能正确解读共用体中存储的数据,通常需要另一个额外的变量,例如:enum ValueType { INT_TYPE, FLOAT_TYPE } type;(通常称为"标签"或"判别式")来记录当前共用体中存储的是哪个成员。例如,在一个结构体中,可以有一个 type 字段指明当前应该使用共用体中的哪个成员。共用体的内存布局还会受到内存对齐规则的影响。编译器可能会在成员之间或共用体末尾添加填充字节,以确保数据在内存中的地址符合特定要求,从而优化访问速度。因此,共用体的实际大小可能不等于其最大成员的大小,而是其对齐要求的整数倍。




