杂货边角(20):匿名非受限联合体实现类的“变长成员”variant member

本文介绍C++中联合体的使用方法及其带来的内存空间节省效果,并通过具体示例展示如何利用联合体实现变长成员,增强代码的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <cstring>

using namespace std;

/*
联合体的使用,最主要的效果便是内存空间的节省,当然额外的附加作用便是灵活性,但是这种灵活性是以牺牲
可读性为代价的
*/
union T {
    string s;//因为string 是非POD类型,string有non-trivial的构造函数,故而系统会删除T的默认构造函数
    //error: union member 'T::s' with non-trivial 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'|
    int n;
public:
    T() { new (&s) string; } //placement new机制,直接在地址上强制类型初始化
    ~T() { s.~string(); }
};

struct Student{
    Student(bool g, int a) : gender(g), age(a) {}
    bool gender;
    int age;
};

class Singer {
public:
    enum Type {STUDENT, NATIVE, FOREIGNER};

    Singer(bool g, int a): s(g,a) { t = STUDENT; }
    Singer(int i) : id(i) { t = NATIVE; }
    Singer(const char* n, int s) {
        int size = (s>9) ? 9 : s;
        memcpy(name, n, size);
        name[s] = '\0';
        t = FOREIGNER;
    }

    ~Singer() {}
private:
    Type t;
    union { //C++11引入的匿名的非受限结构体,从而配合类,可实现“变长成员”定义的效果variant member
        Student s;
        int id;
        char name[10];
    };
};

int main()
{
    T t; //因为T的默认构造函数被删除了,所以如果不显示定义,则会出现error: use of deleted function 'T::T()'

    Singer a(true, 24);
    Singer b(85767);
    Singer c("Jack chou", 41);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值