C++中union的应用剖析

C++中的联合(Union):灵活存储多类型数据的利器 联合是一种特殊的数据结构,它允许在相同的内存空间中存储多种不同类型的成员。不同于结构体(Struct),联合的成员共享同一块内存空间。这意味着在给一个联合变量赋值时,只能使用其中的一个成员。int i;float f;char c;在上述示例中,MyUnion是一个联合类型,它包含了intfloat和char三个成员。这三个成员共享同一块内存空间,即改变其中一个成员的值会影响其他成员的值。 阅读详情

C++中union的应用剖析

作者:袁小凯

华南理工大学计算机研究所北区研发二部

Email – ccplusplus@21cn.com

前言

       熟悉C的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用”.”和”->”来直接访问。在C++出现后,它继承了union并保留了其在C中的特性。但是在C++中的union又有了新的扩展,这需要大家了解,要不然你会感到费解和迷惑。下面我讲两点。

一、在union中存储对象

在C中union中可以存储任意类型的内置数据类型,那么在C++中union是否可以存储对象呢?还是让我们看一个例子吧,这比任何言语都能说明问题,不是吗?

#pragma warning(disable : 4786)

#include <iostream>

 

using namespace std;

 

class TestUnion

{

public:

       TestUnion(long l):data_(l)

       {

       };

       int data_;

};

 

typedef union _tagUtype_

{

       TestUnion obj;

}UT;

 

int main (void)

{

       return 0;

}

哦!太不幸了,这样不行,union中不可以存储TestUnion类的对象,但在C中union可以存储struct呀,为什么不能存储类的对象呢?很简单,请问,在C中union可以存储带有构造函数的struct吗?对了,在C中的struct是没有构造函数的。所以如果C++中union可以存储有构造函数的类的对象就不太符合逻辑,那不是说C++和C完全兼容吗?不错,正因为这一点,C++中union不可以存储有构造函数的类的对象,但是可以存储不带构造函数的类的对象,这样就和C保持一致了,不想信你试试。对TestUnion类的声明进行如下修改:

class TestUnion

{

public:

       int data_;

};

再进行编译,一切OK!。但是这样却失去了C++的构造初始化特性,这样做是没有任何意义的。那么大家是否认为我是在说废话(我也这么认为^_^)。我只是在说其在C++中的语义,并不是推荐大家使用(绝对不推荐)。但是我们可以在union中存储对象的指针,从而引用不同的对象类型。不用我再多说了吧,大家还是试试吧!

二、类中union的初始化

       由于union的共享内存特点,我们可以使我们的类存储不同的型别而不浪费内存空间,在类中我们可以声明一个union存储不同型别的指针,示例如下:

#pragma warning(disable : 4786)

#include <iostream>

 

using namespace std;

 

class TestUnion

{

       enum StoreType{Long,Const_CharP};

       union

       {

              const char* ch_;

              long       l_;

       } data_;

       StoreType stype_;

       TestUnion(TestUnion&);

       TestUnion& operator=(const TestUnion&);

public:

       TestUnion(const char* ch);

       TestUnion(long l);

       operator const char*() const {return data_.ch_;}

       operator long() const {return data_.l_;}

};

 

TestUnion::TestUnion(const char* ch):data_.ch_(ch),stype_(Const_CharP)

{

}

 

TestUnion::TestUnion(long l):data_.l_(l),stype_(Long)

{

}

 

int main (void)

{

       TestUnion pszobj("yuankai");

       TestUnion lobj(1234);

       cout<<static_cast<const char*>(pszobj)<<endl;

       cout<<lobj<<endl;

      

       return 0;

}

 

       哎!真是不幸,编译都通不过,好象没有什么问题呀,为什么呢?data_.ch_(ch)和data_.l_(l)有问题吗?如果你问一个C程序员他会告诉你,绝对没问题。你不会去怀疑编译器有问题吧!不好意思!我一开始就是这么想的,真是惭愧。费解,迷惑。让我们来看看构造TestUnion对象时发生了什么,这样你就会明白了。当创建TestUnion对象时,自然要调用其相应的构造函数,在构造函数中当然要调用其成员的构造函数,所以其要去调用union成员的构造函数,但是其为匿名的,有没有构造函数可调用,所以出错。很明显在C++中union和class一样它可以有构造函数,不能如此直接引用其成员。struct同样有这限制。只要我们给其定义一个构造函数什么问题都解决了。示例如下:

class TestUnion

{

       enum StoreType{Long,Const_CharP};

       union DataUnion                                                //不能匿名

       {

              DataUnion(const char*);                              //声明const char*构造函数

              DataUnion(long);                                          //声明long构造函数

              const char* ch_;

              long       l_;

       } data_;

       StoreType stype_;

       TestUnion(TestUnion&);

       TestUnion& operator=(const TestUnion&);

public:

       TestUnion(const char* ch);

       TestUnion(long l);

       operator const char*() const {return data_.ch_;}

       operator long() const {return data_.l_;}

};

 

TestUnion::TestUnion(const char* ch):data_(ch),stype_(Const_CharP)

{//注意data_(ch),这里直接引用data_

}

 

TestUnion::TestUnion(long l):data_(l),stype_(Long)

{//注意data_(l),这里直接引用data_

}

 

TestUnion::DataUnion::DataUnion(const char* ch):ch_(ch)

{

}

 

TestUnion::DataUnion::DataUnion(long l):l_(l)

{

}

 

       现在再编译,如果还不行,你怀疑编译器有问题是有理由的。好了就写这么多吧!希望对大家有帮助,我可是花了一个下午的时间呀!如果有什么错误,希望来信指出,很希望和大家共同探讨C++,共同进步(ccplusplus@21cn.com)。

 

致谢!

 

C/C++共用体union详解:从内存布局到协议解析实战 在内存资源敏感的嵌入式开发与网络协议解析中,如何高效利用有限的内存空间是工程师持续关注的核心问题。C语言中的结构体(struct)固然直观,但多个字段同时有效时会带来明显的存储冗余。作为与结构体互补的特殊数据类型,共用体(union)通过让所有成员共享同一块内存起始地址,实现“一份空间、多种解释”,在成员互斥的场景下显著压缩内存开销。理解union的内存布局与对齐规则,是发挥其技术价值的关键;而将其与位域结合、配合类型标签构成变体数据,则能优雅地解决报文载荷解析、寄存器映射等真实工程难题。本文结合协议帧处理 阅读详情

相关推荐

深入解析C/C++ union:从内存布局到实战应用与陷阱规避

在C/C++编程中,理解数据的内存布局是底层开发的核心基础。联合体(union)作为一种特殊的数据类型,其所有成员共享同一块内存地址,这一特性使其在特定场景下成为高效的工具。从原理上看,union通过内存重叠实现了类型的灵活解释,而非同时存储多个值,这直接关联到类型双关(type-punning)和底层位操作。其技术价值在于能够节省内存,并直接进行硬件寄存器映射、协议字段解析及高效的类型转换。典型的应用场景包括嵌入式系统开发、网络协议解析以及需要与硬件寄存器或特定内存布局交互的领域。本文聚焦于union联合

weixin_32247165的博客 288

C/C++中的联合体union介绍

目录 union定义与简单使用 内存分配与所占空间 多种访问内存途径共存 数据存储位置 union应用之寄存器读取 union,中文名“联合体、共用体”,在某种程度上是类似结构体struct的一种数据结构,联合体(union)和结构体(struct)同样可以包含很多种数据类型和变量。

会意的博客 4万+

C++联合体(Union)详解:内存共享机制、应用场景与安全实践

在C++编程中,数据结构的内存布局优化是提升程序性能的关键技术之一。联合体(Union)作为一种特殊的数据结构,其核心原理是允许多个成员共享同一块内存空间,从而实现内存的高效复用。这一机制在嵌入式开发、网络协议解析、硬件寄存器映射等对内存和性能敏感的领域具有重要技术价值。通过联合体,开发者可以实现数据的多重解释,例如将同一段内存既作为整型操作又作为字节数组访问,这在处理数据包解析和硬件交互时尤为实用。结合位域(Bit-field)使用,还能实现对寄存器标志位的精细控制。需要注意的是,联合体的使用需遵循严格的

weixin_33508411的博客 333

C、C++中union用法总结

开始的话 已经好长时间没有更新了,对不起自己,更对不起我亲爱的读者,同时也对不起自己开办的这个博客平台。忙,太忙了,忙于找工作,找一份好工作,纠结于去大城市闯呢,还是回到本省的首府城市。大家都在纠结这个问题,也希望大家和我讨论讨论。别的先不说了,都工作这么长时间了,还回过头来总结union,确实有点过分,要是和大家说我一直从事于C++开发,还不懂union,大家可能还真的不信。我们每天都在总

ny1986的专栏 4384

C++17 std::variant:类型安全与性能优化的完美结合

在C++编程中,类型安全是多态数据处理的核心挑战。传统union虽然节省内存但缺乏类型检查,而继承体系又带来性能开销。C++17引入的std::variant通过编译期类型检查机制,在保持高性能的同时实现类型安全。其底层采用智能内存布局,结合类型标记和内存对齐优化,特别适合金融交易、游戏开发等需要处理多类型数据的场景。作为现代C++的重要特性,std::variant与std::visit组合可实现零开销抽象,在ECS架构中实测提升20%性能。对于需要严格类型检查又追求性能的工程场景,这种类型安全容器已成为

weixin_30444105的博客 407

WGS-84 ECEF ENU 坐标系学习记录

地球坐标系固定在地球上而随地球一起在空间做公转和自转运动,因此地球上任一固定点在地球坐标系的坐标就不会由于地球旋转而变化。地心地固直角坐标系和大地坐标系都属于这种坐标系。 一、 几种坐标系 地心地固直角坐标系(ECEF)坐标系 其原点为地球的质心,x轴延伸通过本初子午线(0度经度)和赤道(0deglatitude)的交点。 z轴延伸通过的北极(即,与地球旋转轴重合)。 y轴完成右手坐标系,穿...

YYshuangshuang的博客 1万+

C++关键字之——union

C++关键字之——union

StephenRay的博客 5841

单细胞分析避坑指南:SCTransform和Harmony参数设置详解

本文深入解析了单细胞分析中SCTransform标准化与Harmony批次校正的关键参数设置。针对10x Genomics等数据,详细探讨了如何通过调整`vars.to.regress`、`theta`等核心参数,在有效去除技术噪音的同时,避免过度校正以保留关键的生物学差异,从而提升分析结果的可靠性与可解释性。

weixin_29053073的博客 608

C++之union详解

union的介绍

m0_72542983的博客 4315

Camera AF和FF

Camera按对焦功能可以分为FF(Fixed Focus)和AF(Auto Focus),即固定对焦和自动对焦。固定对焦顾名思义就是焦距是固定的,而自动对焦可以通过移动镜头位置来改变焦距从而实现自动对焦。以前摄像的功能机大多是固定对焦,现在的手机都带有自动对焦功能。 FF模组包括镜头(Lens),传感器(Sensor),红外滤色器(IR Filter),电路板(PCB),镜头支撑(Lens Holder),连接器(Connector)。 Fig 1. FF Module AF模组包括FF模组,音圈马达(V

Coppa的博客 1万+

LeRobot SO100仿真操控避坑指南:从MuJoCo模型调试到实机同步(附参数修正模板)

本文详细解析了LeRobot SO100机械臂在MuJoCo仿真操控中的常见问题与解决方案,包括关节转向符号调试、偏移值校准及实机同步技术。通过实战案例和参数修正模板,帮助开发者高效解决仿真与实机差异,提升机器人开发效率。

weixin_29064009的博客 246

c++中union的应用剖析

原文来自:http://it.114study.com/program/article392928.html  原文中有好多错误,我这里做了一些修改。 前言   熟悉c的程序员都知道union(联合体)的用法,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。在c++出现后,它继承了union并保留了其在c中的特

Change 909

[运动规划算法]基于飞行走廊的轨迹优化

文章目录简介一、介绍二、原理飞行走廊生成三、项目演示参考 简介 Btraj是一个在线的四旋翼无人机的运动规划框架,主要用于未知环境中的自主导航。基于机载状态估计和环境感知,采用基于快速行进(FM *)的路径搜索方法,从基于构建的欧氏距离场(ESDF)中寻找路径,以实现更好的时间分配。通过对环境进行膨胀生成四旋翼无人机的飞行飞行走廊。使用伯恩斯坦多项式将轨迹表示为分段Bezier曲线,并将整个轨迹生成问题转换成凸问题。通过使用Bezier曲线,可以确保轨迹的安全性和高阶动力学可行性,可以将轨迹完全限制在安全

xiewf的博客 8063

Cosmos 项目 Disjoint Set(并查集)数据结构:Union-Find 原理、路径压缩与多语言实现详解

并查集(Disjoint Set / Union-Find / Merge-Find Set)是一种用于维护**互不相交集合(partition)**的经典数据结构,它支持"新建集合、合并两个集合、查询元素所属集合的代表元"三类核心操作,是连通性判断问题中的基础工具。本文以 Cosmos 仓库中 [disjoint_set 目录](https://link.gitcode.com/i/3a45d0

gitblog_09739的博客 925

微信公众号 - 最新详细实现H5网页接入微信支付功能,开发移动端、PC端网站集成使用微信支付流程及示例代码,公众号网页利用JS-SDK/JSAPI/H5支付授权唤起微信支付,可脱离微信环境支付或内置浏

微信公众号,微信支付,网页,移动端,h5,扫码支付,二维码付款,手机网页,电脑pc网页生成支付二维码,js-sdk,jsapi,外部浏览器调起微信支付,脱离微信环境,在微信内置浏览器如何进行微信支付,前端H5微信支付,web网站,vue2,vue3,nuxt2,nuxt3,jquery,微信公众号h5支付流程,如何实现,怎么做,回调报错,redirect_uri参数错误,必须部署才能调试吗,怎么不打包发布就能在本机测试,微信H5支付能力,uniapp微信支付,h5页面调起支付,支付没反应,无效,失败,H5页

🏆 前端领域优质创作者 6103

28、时间敏感网络中可靠性感知的综合路由与调度

本文针对时间敏感网络(TSN)中现有路由与调度机制主要关注时间触发(TT)流量而忽略其他类型流量效用的问题,提出了一种可靠性感知的综合路由与调度机制。通过将具有不同可靠性和延迟要求的各类流量的联合路由与调度问题形式化为基于优化模理论(OMT)的混合整数规划问题,设计了完整的路由约束与调度约束,并分析了不同类型流量的传输效用,设定了优化目标以提升整体网络性能。实验结果表明,该机制在满足TT流量严格时延与可靠性要求的同时,显著提高了AVB和BE等非关键流量的传输效用,实现了多类型流量的高效协同传输。

hhh00的博客 95

【C++】std::variant:安全高效的union替代方案

C++17引入的std::variant是对传统union的类型安全升级。union作为原生共用体,所有成员共享内存但缺乏类型安全,需手动管理生命周期,仅适用于底层开发。std::variant通过自动类型追踪和生命周期管理,支持任意可拷贝类型,内置丰富接口确保运行期安全,可直接用于容器和现代C++特性。两者核心区别在于类型安全和自动化程度:union适合极致性能场景,而variant适用于绝大多数需要多类型处理的业务逻辑。variant额外内存开销极小(仅类型标签),推荐优先使用,除非有严格的底层或性能要

Ape's IT Blog 1034

YOLO126优化:损失篇 | AAAI 2025 | 一种基于尺度的动态(SD)损失,根据目标大小动态调整尺度和位置损失的影响,提高了网络检测不同尺度目标的能力

提出了一种基于尺度的动态(SD)损失,它根据目标大小动态调整尺度和位置损失的影响,提高了网络检测不同尺度目标的能力。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 447

【数据结构与算法】第42篇:并查集(Disjoint Set Union)

并查集是一种树形的数据结构,用于处理不相交集合的合并与查询问题。它支持两种操作:查找(Find)元素属于哪个集合,合并(Union)两个集合。并查集代码极短但思想精巧,配合路径压缩和按秩合并后,时间复杂度接近O(1)。这一篇我们实现并查集,重点讲解路径压缩优化,并用它解决朋友圈问题。

2301_80672009的博客 622

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

NJUのC++课:数据类型

黑union,为了说明C++中多态的好。

chenyongxun的博客 737

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

C++ 的一些基础知识(二)

本文深入探讨了C++中多个关键特性的底层原理和应用场景。关于volatile关键字,文章澄清了其核心价值在于嵌入式/硬件编程、信号处理等底层场景,而非多线程同步。对于static关键字,详细解析了其在不同上下文(全局变量、函数、类成员)中的语义差异和作用。inline关键字的真正作用是解决头文件函数重复定义问题,而非强制内联优化。命名空间的引入有效解决了全局命名污染问题,提升了代码模块化程度。文章还对比了using、typedef和#define的区别,分析了sizeof运算符的编译期特性,并澄清了stru

Serven的博客 2057

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C/C++联合体与枚举深度解析:内存布局、实战应用与踩坑总结

在C/C++编程中,自定义类型是构建高效、可读代码的重要基石。联合体(union)与枚举(enum)作为两类特殊的自定义类型,常被初学者忽略,却在嵌入式开发、通信协议解析、状态机设计等场景中发挥着不可替代的作用。本文从底层原理出发,深入剖析联合体的内存布局与对齐规则,解释其“一块内存多种解读”的核心机制;同时探讨枚举在消除魔法数字、定义语义化常量以及实现位标志组合中的价值。结合真实工程案例,展示如何用“枚举+联合体”设计带标签的联合结构,实现固定大小的消息传递与安全的类型切换。针对C++11后的强类型枚举和

weixin_31766003的博客 292

13. C++17新特性-std::variant

C++17引入的std::variant解决了传统union在类型安全和生命周期管理上的缺陷,提供了严格类型保证的和类型实现。它采用标签联合体机制,自动处理内存对齐、构造/析构函数调用,并通过索引标签跟踪当前活跃类型。std::variant支持三种数据提取方式:异常驱动的std::get、指针探测的std::get_if以及基于std::visit的模式匹配。其典型应用包括替代继承多态、构建状态机和解析器等场景。通过std::monostate可处理无默认构造类型的情况。作为现代C++的重要特性,std:

qq_56402998的博客 447
上一篇: 侯老师--STL源码剖析--书中的疑问二
下一篇: C++模板的定制四:定制成员函数和缺省类参
winmain
博客等级 码龄26年 5粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值