c++ union使用笔记

news2025/3/15 6:08:52

c++ union使用笔记

      • 一、联合的简单使用
      • 二、联合与枚举结合
      • 三、匿名联合(Anonymous Union)
      • 四、关键注意事项
      • 五、C++17 扩展:`std::variant`

C++联合(union)是一种特殊的数据结构,允许在相同内存位置存储不同的数据类型,其核心价值在于 节省内存空间(所有成员共享同一块内存)。以下是联合的详细说明和应用示例:


一、联合的简单使用

特点

  • 所有成员共享同一块内存(大小为最大成员的大小)
  • 同一时间只能使用一个成员
  • 默认访问权限为 public

示例

union NumericData {
    int i;
    double d;
    char c;
};

int main() {
    NumericData data;
    data.i = 42;                // 存储整数
    std::cout << data.i << "\n"; // 输出 42
    
    data.d = 3.14;              // 覆盖内存,存储双精度浮点数
    std::cout << data.d << "\n"; // 输出 3.14
    
    // 注意:此时访问 data.i 将得到无意义的值!
    return 0;
}

二、联合与枚举结合

核心思想:通过枚举标记联合当前存储的数据类型,避免错误访问。

示例1

// 定义数据类型标签
enum class DataType { INT, DOUBLE, CHAR };

struct DataContainer {
    DataType tag; // 类型标记
    union {
        int i;
        double d;
        char c;
    };
};

int main() {
    DataContainer dc;
    dc.tag = DataType::INT;
    dc.i = 100;

    // 安全访问:先检查类型标记
    if (dc.tag == DataType::INT) {
        std::cout << dc.i << "\n"; // 输出 100
    }

    dc.tag = DataType::DOUBLE;
    dc.d = 2.718;
    // 错误示例:未检查标记直接访问将导致未定义行为
    return 0;
}

示例2

#include <iostream>
#include <string>

enum class DataType { INT, DOUBLE, STRING };

struct Variant {
    DataType type;
    union {
        int i;
        double d;
        std::string s;
    };

    // 构造函数
    Variant(int val) : type(DataType::INT), i(val) {}
    Variant(double val) : type(DataType::DOUBLE), d(val) {}
    Variant(const std::string& val) : type(DataType::STRING) {
        new (&s) std::string(val); // Placement new 构造字符串
    }

    // 析构函数
    ~Variant() {
        if (type == DataType::STRING) {
            s.~basic_string(); // 手动析构字符串
        }
    }

    // 拷贝构造函数
    Variant(const Variant& other) : type(other.type) {
        switch (type) {
            case DataType::INT: i = other.i; break;
            case DataType::DOUBLE: d = other.d; break;
            case DataType::STRING: new (&s) std::string(other.s); break;
        }
    }

    // 赋值运算符
    Variant& operator=(const Variant& other) {
        if (this != &other) {
            if (type == DataType::STRING) s.~basic_string();
            type = other.type;
            switch (type) {
                case DataType::INT: i = other.i; break;
                case DataType::DOUBLE: d = other.d; break;
                case DataType::STRING: new (&s) std::string(other.s); break;
            }
        }
        return *this;
    }
};

三、匿名联合(Anonymous Union)

特点

  • 没有名称,直接访问成员
  • 常用于结构体或类内部简化访问
  • C++11 起允许包含非平凡类型(如 string,但需谨慎使用)

示例

struct Data {
    enum { INT, FLOAT } type;
    union { // 匿名联合
        int i;
        float f;
    };
};

// 使用示例
Data d;
d.type = Data::INT;
d.i = 42; // 直接访问匿名联合成员

四、关键注意事项

  1. 内存覆盖:修改一个成员会影响其他成员的值。
  2. 类型安全:必须手动跟踪当前有效成员(通常结合枚举)。
  3. 构造/析构:C++11 起支持含有非平凡类型的联合,但需显式管理生命周期。
  4. 应用场景
    • 协议解析(如网络数据包)
    • 硬件寄存器映射
    • 内存敏感型应用(嵌入式系统)

五、C++17 扩展:std::variant

对于需要更安全的类型存储,推荐使用 std::variant(C++17 引入):

#include <variant>
#include <string>

int main() {
    std::variant<int, double, std::string> data;
    data = 42; // 存储 int
    data = "Hello"; // 存储 string
    // 自动跟踪当前类型,无需手动标记
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2315282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android中的Wifi框架系列

Android wifi框架图 Android WIFI系统引入了wpa_supplicant&#xff0c;它的整个WIFI系统以wpa_supplicant为核心来定义上层接口和下层驱动接口。 Android WIFI主要分为六大层&#xff0c;分别是WiFi Settings层&#xff0c;Wifi Framework层&#xff0c;Wifi JNI 层&#xff…

【含文档+PPT+源码】基于Python的图书管理系统的设计与实现

项目介绍 本课程演示的是一款基于Python的图书管理系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 带你从零开始部署运行本套系统 该项目附…

开源工具利器:Mermaid助力知识图谱可视化与分享

在现代 web 开发中&#xff0c;可视化工具对于展示流程、结构和数据关系至关重要。Mermaid 是一款强大的 JavaScript 工具&#xff0c;它使用基于 Markdown 的语法来呈现可定制的图表、图表和可视化。对于展示流程、结构和数据关系至关重要。通过简单的文本描述&#xff0c;你可…

茂捷M1001电感式编码器芯片TSSOP28管脚,国产电感式编码器IC

简述&#xff1a; M1001 电感式编码器芯片是一款专为高精度位置检测而设计的芯片产品&#xff0c;采用先进的电感技术&#xff0c;能够精确测量旋转物体的位置和角度。芯片具有 SIN/COS、模拟、PWM、SENT、SPI、I2C等多种角度输出功能&#xff0c;具有高分辨率、宽工作温度范围…

LeetCode-跳跃游戏 II

方法一&#xff1a;反向查找出发位置 我们的目标是到达数组的最后一个位置&#xff0c;因此我们可以考虑最后一步跳跃前所在的位置&#xff0c;该位置通过跳跃能够到达最后一个位置。 如果有多个位置通过跳跃都能够到达最后一个位置&#xff0c;那么我们应该如何进行选择呢&a…

数据结构——双向链表dlist

前言&#xff1a;大家好&#x1f60d;&#xff0c;本文主要介绍了数据结构——双向链表dlist 一 双向链表定义 1. 双向链表的节点结构 二 双向链表操作 2.1 定义 2.2 初始化 2.3 插入 2.3.1 头插 2.3.2 尾插 2.3.3 按位置插 2.4 删除 2.4.1 头删 2.4.2 尾删 2.4.3 按…

IDEA 一键完成:打包 + 推送 + 部署docker镜像

1、本方案要解决场景&#xff1f; 想直接通过本地 IDEA 将最新的代码部署到远程服务器上。 2、本方案适用于什么样的项目&#xff1f; 项目是一个 Spring Boot 的 Java 项目。项目用 maven 进行管理。项目的运行基于 docker 容器&#xff08;即项目将被打成 docker image&am…

图像分类数据集

《动手学深度学习》-3.5-学习笔记 # 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式&#xff0c; # 并除以255使得所有像素的数值均在0&#xff5e;1之间 trans transforms.ToTensor()#用于将图像数据从 PIL 图像格式&#xff08;Python Imaging Library&#xff…

设计模式之美

UML建模 统一建模语言&#xff08;UML&#xff09;是用来设计软件的可视化建模语言。它的语言特点是简单 统一 图形化 能表达软件设计中的动态与静态信息。 UML的分类 动态结构图&#xff1a; 类图 对象图 组件图 部署图 动态行为图&#xff1a; 状态图 活动图 时序图 协作…

2025-03-15 学习记录--C/C++-PTA 练习3-4 统计字符

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 练习3-4 统计字符 本题要求编写程序&#xff0c;输入10个字符&#xff0c;统计其中英文字母、空格或回车、…

802.11标准

系列文章目录 文章目录 系列文章目录一、相关知识二、使用步骤1.802.11修正比较2.802.11ac 三、杂记 一、相关知识 跳频扩频&#xff1a;射频信号可分为窄带信号和扩频信号。如果射频信号的带宽大于承载数据所需的带宽&#xff0c;该信号就属于扩频信号。跳频扩频(FHSS)是一种…

母婴商城系统Springboot设计与实现

项目概述 《母婴商城系统Springboot》是一款基于Springboot框架开发的母婴类电商平台&#xff0c;旨在为母婴产品提供高效、便捷的在线购物体验。该系统功能全面&#xff0c;涵盖用户管理、商品分类、商品信息、商品资讯等核心模块&#xff0c;适合母婴电商企业或个人开发者快…

C#通过API接口返回流式响应内容---分块编码方式

1、背景 上一篇文章《C#通过API接口返回流式响应内容—SSE方式》阐述了通过SSE&#xff08;Server Send Event&#xff09;方式&#xff0c;由服务器端推送数据到浏览器。本篇是通过分块编码的方式实现 2、效果 3、具体代码 3.1 API端实现 [HttpGet] public async Task Chu…

游戏引擎学习第158天

回顾和今天的计划 我们在这里会实时编码一个完整的游戏&#xff0c;没有使用引擎或库&#xff0c;一切都由我们自己做所有的编程工作&#xff0c;游戏中的每一部分&#xff0c;无论需要做什么&#xff0c;我们都亲自实现&#xff0c;并展示如何完成这些任务。今天&#xff0c;…

[新能源]新能源汽车快充与慢充说明

接口示意图 慢充接口为交流充电口&#xff08;七孔&#xff09;&#xff0c;快充接口为直流充电口&#xff08;九孔&#xff09;。 引脚说明 上图给的是充电口的引脚图&#xff0c;充电枪的为镜像的。 慢充接口引脚说明 快充接口引脚说明 充电流程 慢充示意图 慢充&…

在IDEA中连接达梦数据库:详细配置指南

达梦数据库&#xff08;DM Database&#xff09;作为国产关系型数据库的代表&#xff0c;广泛应用于企业级系统开发。本文将详细介绍如何在IntelliJ IDEA中配置并连接达梦数据库&#xff0c;助力开发者高效完成数据库开发工作。 准备工作 1. 下载达梦JDBC驱动 访问达梦官方资…

基于yolov8+streamlit实现目标检测系统带漂亮登录界面

【项目介绍】 基于YOLOv8和Streamlit实现的目标检测系统&#xff0c;结合了YOLOv8先进的目标检测能力与Streamlit快速构建交互式Web应用的优势&#xff0c;为用户提供了一个功能强大且操作简便的目标检测平台。该系统不仅具备高精度的目标检测功能&#xff0c;还拥有一个漂亮且…

软件性能测试与功能测试联系和区别

随着软件开发技术的迅猛发展&#xff0c;软件性能测试和功能测试成为了确保软件质量的两个重要环节。那么只有一字之差的性能测试和功能测试分别是什么?又有哪些联系和区别呢? 一、软件性能测试是什么?   软件性能测试是为了评估软件系统在特定条件下的表现&#xff0c;包…

Axure设计之堆叠柱状图教程(中继器)

堆叠柱状图是一种常用的数据可视化工具&#xff0c;它通过在同一柱状图内堆叠不同类别的数据&#xff0c;以展示每个类别在总体中的贡献或占比。堆叠柱状图不仅可以帮助我们观察数据的总量&#xff0c;还能清晰地揭示各部分之间的关系和变化趋势。以下是一个使用Axure制作动态效…

本地部署Hive集群

规划 服务机器Hive本体部署在Node1元数据服务所需的关系型数据库(MYSQL)部署在Node1 安装MYSQL数据库 # 更新密钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022# 安装Mysql yum库 rpm -Uvh http://repo.mysql.com//mysql57-community-release-el7-7.noarch.…