C++11新特性之非受限联合体

27 篇文章 1 订阅

1. 取消枚举对数据成员类型的限制

联合体是C/C++语言中的一种数据结构。在这种数据结构中我们可以定义多种不同类型的数据,但这些数据却共享相同的一段内存空间。在C++98中,针对联合体中的数据类型有一些限制,即联合体中不能有非POD类型,静态类型以及引用类型。比如在

C++98标准下,下面的代码将不会通过编译:

class Person
{
public:
    Person(bool gender, int age):m_gender(gender),m_age(age){}
private:
    bool m_gender;
    int  m_age ;
    
};

union U
{
    Person s;
    int id;
    char name[10];
};

在联合体U中,Person 类型的变量s有一个自定义的构造函数,所以s是一个非POD类型,在C++98标准下,会编译失败。

在C++11标准中,取消了枚举类型对数据成员类型的限制,即任何非引用类型都可以成为联合体的数据成员,这种联合体也称为非受限联合体(Unrestricted Union)。

2. 初始化

在C++98标准下,枚举类型中没有出现在初始化列表中的数据成员会被自动赋值,但这有时候会带来迷惑,请看下面的代码:

union U
{
    int s;
    double id;
    char name[5];
};
U u = {0} ;

上面代码中,用初始化列表的方式对枚举u赋初值0,试图将第一个成员变量s赋值为0,但实际上u所占的8字节空间会全部被赋值为0。

在C++11标准中,当联合体中有一个非POD的成员,并且该非POD成员有非平凡的构造函数,那么这个联合体的默认构造函数就会被编译器删除,同理,其他的特殊成员函数比如默认拷贝构造函数,拷贝赋值构造函数及析构函数,也遵循这个标准。比如下面的例子:

Union U
{
    string str ;  //str 有非平凡构造函数
    double d ;
};

int main()
{
    U u ; //编译失败,u的构造函数被删除
}

联合体U中的数据成员str有非平凡的构造函数,所以编译器会删除U的默认构造函数,因而u的构造就失败了。那么如何解决这种情况呢?办法是为联合体自定义一个构造函数:

Union U
{
    string str ;  //str 有非平凡构造函数
    double d ;
public:
    U(){new (&str) string;}  //自定义构造函数
    ~U(){str.~string();}     //自定义析构函数
};

int main()
{
    T t ; 
}
在上面的代码中,我们为U定义了构造和析构函数,这样就可以顺利编译通过了,只是要注意的是,当析构Union U的时候也必须是一个string对象,否则会导致析构错误。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值