C++怎么定义联合体 C++中union和类混合用法有哪些

来源:Nodejs社区作者:印尼程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《C++怎么定义联合体 C++中union和类混合用法有哪些》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++怎么定义联合体 C++中union和类混合用法有哪些》有用,将其分享出去将是对创作者最好的鼓励。

C++中的联合体(union)是一种能让多个不同数据成员共享同一块内存空间的特殊数据类型,它和结构体类似但内存使用方式差异很大。联合体在需要节省内存或者处理同一数据不同表示的场景下非常实用,而和类结合使用还能扩展其功能边界。

C++怎么定义联合体 C++中union和类混合用法有哪些

C++中联合体的基础定义方式

联合体的定义使用union关键字,基础语法和结构体类似,所有成员共享起始地址相同的内存空间,联合体的大小等于其最大成员的大小。

下面是一个简单的联合体定义示例:

#include <iostream>
using namespace std;

// 定义基础联合体
union Data {
    int int_val;
    float float_val;
    char char_val;
};

int main() {
    Data d;
    // 给int成员赋值
    d.int_val = 10;
    cout << "int_val: " << d.int_val << endl;
    // 此时float_val的值是未定义的,因为内存被int_val占用
    cout << "float_val: " << d.float_val << endl;
    
    // 给float成员赋值,会覆盖之前int_val的内存
    d.float_val = 3.14f;
    cout << "float_val: " << d.float_val << endl;
    cout << "int_val: " << d.int_val << endl;
    return 0;
}

上述代码中,Data联合体的三个成员共享同一块内存,修改其中一个成员的值会影响其他成员的解读结果。

union和类混合用法的常见形式

C++中的union可以包含构造函数、析构函数、成员函数,也可以有访问权限控制,这些特性让它能和类的特性结合使用,常见的混合用法有以下几种。

带访问控制的联合体

联合体可以像类一样使用publicprivateprotected访问修饰符,限制成员的访问范围。

#include <iostream>
using namespace std;

union PrivateUnion {
private:
    int secret_int;
    float secret_float;
public:
    void set_int(int val) {
        secret_int = val;
    }
    int get_int() {
        return secret_int;
    }
    void set_float(float val) {
        secret_float = val;
    }
    float get_float() {
        return secret_float;
    }
};

int main() {
    PrivateUnion pu;
    pu.set_int(20);
    cout << "get_int: " << pu.get_int() << endl;
    pu.set_float(2.718f);
    cout << "get_float: " << pu.get_float() << endl;
    // 直接访问secret_int会编译报错,因为是私有成员
    // pu.secret_int = 10;
    return 0;
}

联合体作为类的成员

可以将联合体作为类的内部成员,用来封装需要共享内存的数据,类对外提供统一的访问接口。

#include <iostream>
#include <string>
using namespace std;

class DataWrapper {
private:
    // 内部联合体定义
    union InnerUnion {
        int id;
        float score;
    };
    InnerUnion data;
    bool is_int_type; // 标记当前存储的数据类型
public:
    DataWrapper(int val) {
        data.id = val;
        is_int_type = true;
    }
    DataWrapper(float val) {
        data.score = val;
        is_int_type = false;
    }
    void print_data() {
        if (is_int_type) {
            cout << "存储的是int类型,值: " << data.id << endl;
        } else {
            cout << "存储的是float类型,值: " << data.score << endl;
        }
    }
};

int main() {
    DataWrapper dw1(100);
    dw1.print_data();
    DataWrapper dw2(95.5f);
    dw2.print_data();
    return 0;
}

包含类类型成员的联合体

C++11之后,联合体可以包含具有非平凡构造函数和析构函数的类类型成员,不过需要手动管理这些成员的构造和析构。

#include <iostream>
#include <string>
using namespace std;

union ClassMemberUnion {
    int num;
    string str; // string是类类型,有非平凡构造和析构
    // 需要显式定义构造函数和析构函数
    ClassMemberUnion() : num(0) {}
    ~ClassMemberUnion() {
        // 这里需要根据实际存储的类型调用对应成员的析构
        // 实际使用中需要额外标记当前激活的成员
    }
    void set_num(int val) {
        num = val;
    }
    void set_str(const string& val) {
        new (&str) string(val); // 手动构造string成员
    }
    void clear_str() {
        str.~string(); // 手动析构string成员
    }
};

int main() {
    ClassMemberUnion cmu;
    cmu.set_num(50);
    cout << "num: " << cmu.num << endl;
    cmu.set_str("hello");
    cout << "str: " << cmu.str << endl;
    cmu.clear_str(); // 使用完string成员后手动析构
    return 0;
}

union和类混合使用的注意事项

  • 联合体的所有成员共享内存,同一时间只能有一个成员是有效的,需要额外维护类型标记来明确当前存储的数据类型。
  • 如果联合体包含有非平凡构造/析构的类类型成员,必须手动管理这些成员的生命周期,编译器不会自动调用对应的构造和析构函数。
  • 联合体的大小是其最大成员的大小,即使其他成员很小,也会占用对应大小的内存,需要结合场景评估内存收益。
  • 匿名联合体和类结合使用时,可以直接访问其成员,不需要通过联合体变量名,适合简单的共享内存场景。

适用场景总结

union和类混合的用法适合以下场景:需要节省内存空间,同一变量可能有多种类型表示,需要封装共享内存的逻辑对外提供统一接口。比如协议解析中同一个字段可能有不同的数据类型,或者嵌入式开发中需要优化内存占用的场景。合理使用这种用法可以在保证功能的同时提升内存使用效率。

C++union联合体类混合用法修改时间:2026-07-04 23:06:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。