走进C++11(三)“类” 类型的union

C++:34---union:联合/共用体,一种节省空间的类 一、联合(union)概述联合(union)是一种特殊的类一个union可以有多个数据成员,但是在任意时刻只有一个数据成员可以有值。当我们给union的某个成员赋值之后,该union的其... 阅读详情

Union其实是不想介绍的一个关键字,因为union的功能即将被C++17标准中的variant所代替,而且variant更加安全。但是还是要在这里介绍一下。

 

union(联合体)和struct相似,也可以包含多个数据成员,但是不同的是同时只允许一个成员有效,因此经常作为作为节约空间的类使用。

 

C++11中union除了继承c语言的数据共享内存之外,行为上越来越像一个类,比如成员默认是public类型。

 

在C++11以后,很多基础语法都进行了修正。其中 union 的行为向类对象进行了发展,在兼容原有语法定义的基础上进行了扩充:

 

  • 联合体可拥有成员函数(包含构造函数和析构函数),但不能有虚函数。

  • 联合体不能有基类且不能用作基类。

  • 联合体不能拥有引用类型的非静态数据成员。

 

联合体不能含有带非平凡特殊成员函数(复制构造函数、复制赋值运算符或析构函数)的非静态数据成员。(C++11 前)
若联合体含有带非平凡特殊成员函数(复制/移动构造函数,复制/移动赋值,或析构函数)的非静态数据成员,则联合体中的该函数默认被弃置,且需要程序员显式定义它。若联合体含有带非平凡默认构造函数的非静态数据成员,则该联合体的默认构造函数默认被弃置,除非联合体的变体成员拥有一个默认成员初始化器。至多一个变体成员可以拥有默认成员初始化器。(C++11 起)

 

这些说明都很难懂,举两个小例子:

 

struct Point{  Point() {}  Point(int x, int y): x_(x), y_(y) {}  int x_, y_;};union U{  int z;  double w;  Point p; // 在C++03中是不合法(point有一non-trivial建構式),但是在C++11是合法的  U() {} // 由于 Point 成员的存在,必须要定义一个构造函数  U(const Point& pt) : p(pt) {} // 通过初始化列表构造 Point 对象  U& operator=(const Point& pt) { new (&p) Point(pt); return *this; } // 通过原地new方式赋值构造Point对象};

 

#include <iostream>#include <string>#include <vector>union S{    std::string str;    std::vector<int> vec;    ~S() {} // 需要知道哪个成员活跃,仅在联合体式的类中可行};          // 整个联合体占有 max(sizeof(string), sizeof(vector<int>)) 的内存int main(){    S s = {"Hello, world"};    // 在此点,从 s.vec 读取是未定义行为    std::cout << "s.str = " << s.str << '\n';    s.str.~basic_string();    new (&s.vec) std::vector<int>;    // 现在,s.vec 是联合体的活跃成员    s.vec.push_back(10);    std::cout << s.vec.size() << '\n';    s.vec.~vector();}

输出:

 

s.str = Hello, world1

 

需要注意的是

联合体的默认成员访问是 public。

 

解释

 

联合体的大小仅足以保有其最大的数据成员。其他数据成员分配于该最大成员的一部分相同的字节。分配的细节是实现定义的,且从并非最近写入的联合体成员进行读取是未定义行为。许多编译器作为非标准语言扩展,实现读取联合体的不活跃成员的能力。

 

#include <iostream>#include <cstdint>union S{    std::int32_t n;     // 占用 4 字节    std::uint16_t s[2]; // 占用 4 字节    std::uint8_t c;     // 占用 1 字节};                      // 整个联合体占用 4 字节int main(){    S s = {0x12345678}; // 初始化首个成员,s.n 现在是活跃成员    // 于此点,从 s.s 或 s.c 读取是未定义行为    std::cout << std::hex << "s.n = " << s.n << '\n';    s.s[0] = 0x0011; // s.s 现在是活跃成员    // 在此点,从 n 或 c 读取是 UB 但大多数编译器都对其有定义    std::cout << "s.c is now " << +s.c << '\n' // 11 或 00,取决于平台              << "s.n is now " << s.n << '\n'; // 12340011 或 00115678}

 

可能的输出:

 

s.n = 12345678s.c is now 0s.n is now 115678

 

各个成员都如同它是类的仅有成员一样进行分配。

 

可以看出,使用union存在着一些隐患,这是由于union虽然能节约空间。但是它没有类型信息。

 

关注公众号获取更多信息:

 

C++11之非受限制联合体(Unrestricted Union) 文章目录1. 联合体union回顾2. 联合体union的成员3.4. 1. 联合体union回顾 2. 联合体union的成员 3. 4.                                                                                                                                                                                           阅读详情

相关推荐

Unity3D移动平台简单实现

在电子游戏中移动平台可谓是十分常见的,如平台从一处至另一处的来回移动,或当需要玩家触发机关时,平台浮动并按一定的路线移动至目标处。本文主要是在Unity3D引擎下使用少量脚本实现两点之间来回移动平台的最基本功能,是一种比较简单且好理解的移动平台解决方案。 涉及到的点如下: 平台对象的实现 平台移动路线的设定 处于平台上游戏对象(如:玩家)的相对运动 创建平台控制对象 创建平台实...

长溪木可的博客 4683

联合体union

掌握了**的使用,我们通过一段程序来演示一下class Basepublic:private:Student()int id;Base tmp;s.name = "蒙奇·D·路飞";s.tmp.setText("我是要成为海贼王的男人!");return 0;Base notes: 我是要成为海贼王的男人!Student name: 我是要成为海贼王的男人!

f593256的博客 1713

kali2020.2安装出现的问题并附详细解决办法

kali2020.2的安装

weixin_48776804的博客 3049

c++笔记6:union的一种用法

如果有些场景中需要用多种方式调用同一个值,可以用union 定义二维向量结构: struct Vector2 { int a, b; } 定义四维向量结构: struct Vector4 { union { struct { int x, y, z, w; }; struct { Vector2 m, n; }; }; }; 四维向量包含四个数据。除了x,y,z,w一种定义外,还可以利用二维向量。这样四维向量便有了两种使用方式 #include <

luobaotai的博客 412

Win10系统VS2019+Cmake+qhull_8.0.0环境配置

1 qhull 1.1 简要介绍 qhull是一个强大的计算几何库,可以用于计算高维的convex hull, Delaunay triangulation, Voronoi diagram等。 1.2 依赖库 qhull不依赖其他库。 1.3 源码包下载 qhull源码地址:github:https://github.com/qhull/qhull.git 2 Cmake构建项目 2.1 路径 源代码路径:D:/ThirdParty/qhull/qhull_8.0.0构建项目路径:D:/Thi.

wangchenxue的博客 2492

CTFHUB------XSS反射型(WP)

文章目录前言XSS测试平台 前言 一开始我直接在上面写js脚本发现出错,最后发现只能通过下面的输入框来执行XSS测试,于是我们只能用XSS测试平台解决问题 XSS测试平台 注册一个XSS测试平台 这里随便填写 勾选默认模块就够了,点击下一步 这时会出现一个找个将代码复制 拼接到网站后缀name后面,点击send 这时平台会收到一个记录点开即可 得到flag ...

Y4tacker的博客 1万+

联合体(union) in C++【C++学习笔记】

67.联合体(union) in C++ 联合体有点像类类型,或者结构体类型,只不过它一次只能占用一个成员的内存 比如结构体中有四个成员,每一个成员都有着占着不同的字节。而一个联合体只能有一个成员,也就是说如果声明了四个浮点数abcd,他们共用一个内存空间,即4个字节 而人们用联合体来做的事情,是和类型双关紧密相关的 在你想给同一个变量取两个不同的名字时,它真的很有用(引用:???),当然,可读性上是一定比引用要好的 比如有一个正常的abc,有一个坐标轴上的xyz,我想让abc和xyz一一对应,则可以

Mikey99的博客 1638

KEIL MDK 生成bin文件实战:C51与ARM双平台配置指南

本文详细介绍了在KEIL MDK开发环境中,为C51和ARM双平台自动生成BIN文件的实战方法。针对C51平台,通过srec_cat.exe工具编写批处理脚本并集成到KEIL;针对ARM平台,则利用fromelf.exe工具直接配置。文章还提供了通用脚本方案和路径、变量、版本兼容性等常见问题的避坑指南,帮助开发者高效完成嵌入式程序部署。

weixin_29188997的博客 346

c++11中的union

c++11中的union

波波的专栏 3231

中国区ASP服务性规范考试

10、每次现场维护服务,工程师需按照400要求达到现场的时间与客户联系,在抵达现场、故障恢复后两个时间点分别向400报CALL ,如与客户联系变更到现场时间点,也需向400电话备案(400-822-9999)……20、工程师小B 在接到客户故障申报后赶到客户现场,发现问题无法解决,于是及时将情况反馈至技术支持响应工程师小C ,小B 就和小C 协商由小C 远程解决此问题,后小B 离开客户现场。18、小L 到客户现场交付安装服务。6、EPMS 中上载初验证书的命名规则为:合同号+初验的客户签署日期……

2301_76197693的博客 1909

遥感目标检测数据集汇总

文章目录1. 光学数据集1.1 DIOR1.2 LEVIR1.3 DOTA1.4 RSOD1.5 NWPU VHR-101.6 VEDAI1.7 COWC1.8 ITCVD1.9 DIUx xView 20181.10 HRSC20161.11 TAS1.12 SZTAKI‐INRIA1.13 UCAS AOD1.14 DLR 3K Vehicle2. SAR2.1 SSDD2.2 SSDD+2....

quanwei的博客 6万+

C++中union的应用剖析

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

942

Cyclone DDS背景技术

DDSI标准与DDS 1.2和1.4标准密切相关,DDSI中的实体与DCPS中的实体之间有明确的对应关系。但是,这种对应关系不是一一对应的。 此处,仅仅对DDSI规范的概念进行描述,暂不涉及Eclipse Cyclone DDS实现的细节。DDSI规范的概念将帮助对互操作性interoperability感兴趣的技术人员了解规范的外延边界和Eclipse Cyclone DDS实现的开始。

pony12的专栏 948

c++11中,含有类类型的union

当union含有类类型成员时,如果该类类型定义了默认构造函数或拷贝控制成员,则编译器为union合成对应的版本并将其声明为删除的。 举例说明: 例1: #include using namespace std; class base{ public: base(){cout << "base()" <<endl;} ~base(){cout << "~base()" << endl

ml422524的专栏 3732

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++11中枚举enum和union,顺带说一下内存对齐和大小端问题

这两个不太常用的小知识点,今天碰到了,所以特来总结一下。union类union X { int a; struct { short b; short c; }; }; int main(){ X x; x.a = 0x20150810; printf("%x,%x\n", x.b, x.c); retur

haolexiao的专栏 2135

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

c++ 类中定义类_C++:34union:联合/共用体,一种节省空间的类

一、联合(union)概述联合(union)是一种特殊的类一个union可以有多个数据成员,但是在任意时刻只有一个数据成员可以有值。当我们给union的某个成员赋值之后,该union的其它成员就变成未定义的状态了。分配给一个union对象的存储空间至少要能容纳它的最大的数据成员类的某些特性对union同样适用,但并非所有特性都如此:union不能含有引用类型的成员,union的成员可以是...

weixin_36124888的博客 1104

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C++11新特性(86)-类类型的union成员(2)

经过一番准备,我们进入正题。   类类型的union成员 C++的早期版本不允许union的成员是定义了构造函数或拷贝控制成员的类类型成员,C++11中取消了这个限制。但是也别高兴得太早,因为这类union在发生涉及到类类型成员的值转换时需要根据需求调用相关类成员的构造函数或析构函数。   假设我们有下面的StrValue类。引入这个类的目的是为了在对象操作时可以输出日志信息。 ...

面向对象思考 1736

C++中的Union: 内存与类型转换技巧

union定义了一个可以存储多种类型但任意时刻只能存储其中一种类型的数据结构。union的大小至少是其成员中最大类型的大小。

karl2000的专栏 1333

【C++随笔01】联合体union —— 一种节省空间的类

定义union定义的语法如下:c++// ...其中,UnionName为该union类型的名称,unionMember1、unionMember2等为union的成员,可以是任何 C++ 数据类型(包括自定义类型),也可以是数组或指针。union的成员占用同一块内存空间,它们的大小取决于成员中占用内存最大的类型。可以使用.和->运算符来访问union中的成员变量。但需要注意的是,不同的成员变量共享同一段内存,因此只能同时访问一个成员变量// demo1int m_id;

junxuezheng的博客 1468

C++笔记 19.6 union类

primer C++笔记 union:一种节省空间的类 定义union 使用union类型 匿名union 含有类类型成员的union 使用类管理union成员 //vs2017 class Token { public: Token() : tok(INT), ival{ 0 } {} Token(const Token &t) : tok(t.tok) { copyUnion(t); }; Token &operator=(const Token&); //作

qq_36333986的博客 303

union 的正确食用方法

介绍一下 cpp 中 union 类型的概念。

Kovnt的博客 1422

C++11新特性(85)-类类型的union成员(1)

接下来的两篇文章介绍C++11的最后一个新特性:类类型的union成员。这个新特性涉及的内容较多,所以本文先做一些不属于C++11新特性的准备工作。   匿名union 我们通过一个例子类说明。假设有以下函数: 这 个函数的功能是根据参数rt的要求产生随机数并转换为字符串。代码中首先为每一种场景准备了一个临时变量用于存储随机数生成器的输出。但是观察接下来的代 码我们发现这两个变量并...

面向对象思考 3026

11.struct与union计算方式、编译的四个过程、c++11新特性等

C++知识点41.Struct和union在内存中占用空间大小的计算2.final 和override3.STL4.C++11新特性5.C++编译的四个过程6.C++中的strict和class的区别7.枚举8.std::initialize_list9.线程池的实现10.函数11.const和define的区别 1.Struct和union在内存中占用空间大小的计算 struct和union在内...

107 9972

C++基础(十一):枚举类型、union

本文为《C++ Primer》的读书笔记 目录限定 / 不限定 作用域的枚举枚举成员和类一样,枚举也定义新的类型指定`enum` 的大小枚举类型的前置声明形参匹配与枚举类型 限定 / 不限定 作用域的枚举 C++ 包含两种枚举: 限定作用域的 (scoped enumeration) (由 C++11 新标准引入) 定义限定作用域的枚举类型的一般形式是:首先是关键字enum class (或者等价地使用enum struct), 随后是枚举类型名字以及用花括号括起来的以逗号分隔的枚举成员列表: /

连理o的博客 1129

C++11非受限联合体(union)

C++11非受限联合体(union) 在 C/C++ 中,联合体(Union)是一种构造数据类型。在一个联合体内,我们可以定义多个不同类型的成员,这些成员将会共享同一块内存空间。老版本的 C++ 为了和C语言保持兼容,对联合体的数据成员的类型进行了很大程度的限制,这些限制在今天看来并没有必要,因此 C++11 取消了这些限制。 C++11 标准规定,任何非引用类型都可以成为联合体的数据成员,这种联合体也被称为非受限联合体。例如: class Student{ public: Student(bool

ccc369639963的博客 1104

union:一种节省空间的类

当我们给union的某个成员赋值之后,该union的其他成员就变成未定义的状态了。分配给一个union对象的存储空间至少要能容纳它的最大的数据成员。 union不能含有引用类型的成员,除此之外,它的成员可以是绝大多数类型。在C++11新标准中,含有构造函数或析构函数的类类型也可以作为union的成员类型。为union的一个数据成员赋值会令其他数据成员变成未定义的状态。含有类类型成员的union

tengyft的专栏 1148
上一篇: 走进C++11(二)面向对象之enum 强类型枚举
下一篇: 走进C++11(四)override/final
Max_Cong
博客等级 码龄10年 281粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值