C++的union

C++中Union和Struct的特性比较及其内存占用
文章讨论了C++中的union和struct的数据类型,强调了它们的默认访问权限差异,以及union如何在内存中共享空间。union的大小由其最大成员决定,当赋值时会覆盖之前成员的值。示例代码展示了union和struct在位字段使用上的差异,以及sizeof运算符在不同类型对象上的应用。
  1. union的默认访问权限为public,和struct一样,class则是private,他们的子类也是如此,(class和struct还有struct无法作为模板这方面的不同点)
  2. union所有成员共同使用一块内存,因此union中只能有一个成员被赋值,union的内存大小等于成员中内存最大的内存(比如有一个int和byte成员,union的大小为int所占的内存大小),每次重新赋值则会覆盖前面赋值的成员的值。
union U {

    unsigned short int aa;

    struct {

        unsigned int bb: 7;//(bit 0-6)

        unsigned int cc: 6;//(bit 7-12)

        unsigned int dd: 3;//(bit 13-15)
    };
};

struct UU{

    unsigned int bb: 7;//(bit 0-6)

    unsigned int cc: 6;//(bit 7-12)

    unsigned int dd: 3;//(bit 13-15)
};

int main() {
    unsigned short int a;
    U u;
    u.aa = 10;
    UU uu;
    
    // 说明U取的大小为struct的大小,而不是unsigned short int的值,因为unsigned short int的大小装不下一个结构体
    cout << sizeof(a) << endl;		// 输出2
    cout << sizeof(u) << endl;		// 输出4
    cout << sizeof(UU) << endl;		// 输出4
    cout << sizeof(uu) << endl;		// 输出4
    cout << sizeof(U) << endl;		// 输出4


    return 0;
}
### C++ union 的定义、用法及注意事项 C++ 中的 `union` 是一种特殊的数据结构,它允许在同一个内存位置存储不同的数据类型。与结构体(`struct`)不同的是,`union` 的所有成员共享同一块内存空间,因此在同一时刻只能保存其中一个成员的值。这种特性使得 `union` 在某些特定场景下非常有用,例如需要节省内存或者处理多种数据类型的联合存储时。 #### 定义和基本用法 `union` 的定义方式类似于结构体,但使用关键字 `union`。以下是一个简单的示例: ```cpp union MyUnion { int i; float f; char c; }; ``` 在这个例子中,`MyUnion` 类型的变量可以存储一个整数、浮点数或字符,但由于它们共享同一块内存,所以一次只能保存其中一个成员的值[^2]。 在程序中使用 `union` 变量的方式与使用结构体类似。可以通过点号操作符访问其成员: ```cpp int main() { MyUnion u; u.i = 10; std::cout << "u.i: " << u.i << std::endl; // 输出 10 u.f = 3.14; std::cout << "u.f: " << u.f << std::endl; // 输出 3.14 std::cout << "u.i: " << u.i << std::endl; // 输出由于共享内存,值变为不确定 u.c = 'A'; std::cout << "u.c: " << u.c << std::endl; // 输出 'A' std::cout << "u.i: " << u.i << std::endl; // 输出由于共享内存,值变为不确定 return 0; } ``` 上述代码展示了如何通过 `union` 来存储和访问不同类型的数据,同时也说明了当修改一个成员时,其他成员的值会变得不可预测,因为它们共享同一块内存。 #### 核心特性 - **内存共享**:`union` 的所有成员共享相同的内存位置,这意味着对一个成员的修改会影响其他成员的值。 - **大小决定**:`union` 的大小等于其最大成员的大小,这是为了确保能够容纳最大的数据类型[^1]。 - **单一成员访问**:在同一时间只能使用一个成员,否则将引发未定义的行为[^3]。 #### 注意事项 - **避免存储过大类型**:由于 `union` 的大小由其最大成员决定,因此应避免在 `union` 中存储过大的数据类型,以防止浪费内存资源[^3]。 - **谨慎处理成员赋值**:在同一时间只能使用一个成员,如果尝试同时使用多个成员,可能会导致未定义行为。 - **跨平台兼容性**:由于 `union` 的内存布局依赖于编译器和平台,因此在不同平台上可能表现不一致,需要注意移植性问题。 #### 高级应用场景 `union` 常用于以下几种高级场景: - **节省内存**:当需要在一个对象中存储多种类型的数据,但每次只需要使用其中一种时,`union` 可以有效减少内存占用。 - **硬件编程**:在嵌入式系统开发中,`union` 可用于直接映射寄存器的不同位字段表示。 - **网络协议解析**:在网络通信中,`union` 可以用来解析具有多种格式的数据包头。 例如,在处理网络协议时,`union` 可能被用来解析 IP 地址的不同表示形式: ```cpp union IPAddress { uint32_t ipAsInt; struct { uint8_t octet1; uint8_t octet2; uint8_t octet3; uint8_t octet4; } ipAsOctets; }; int main() { IPAddress ip; ip.ipAsInt = 0x7F000001; // 127.0.0.1 in hexadecimal std::cout << "IP Address: " << static_cast<int>(ip.ipAsOctets.octet1) << "." << static_cast<int>(ip.ipAsOctets.octet2) << "." << static_cast<int>(ip.ipAsOctets.octet3) << "." << static_cast<int>(ip.ipAsOctets.octet4) << std::endl; return 0; } ``` 此例展示了如何利用 `union` 来同时访问整型数值及其分解后的四个字节部分,这对于网络地址的转换非常有用[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值