如何在Union中初始化非POD成员

时间:2014-04-11 06:21:12

标签: c++ c++11 constructor unions

在c ++ 11中,Union支持非POD成员。我想在构造函数中初始化一个非POD成员。

在维基百科c ++ 11 page上,它使用了一个展示位置' new'初始化非POD成员。

#include <new> // Required for placement 'new'.

struct Point {
    Point() {}
    Point(int x, int y): x_(x), y_(y) {}
    int x_, y_;
};

union U {
    int z;
    double w;
    Point p; // Illegal in C++03; legal in C++11.
    U() {new(&p) Point();} // Due to the Point member, a constructor definition is now required.
};

我想知道如果我使用ctor-initializer-list而不是place&#39; new&#39;会有什么不同吗?

U() : p() {}

2 个答案:

答案 0 :(得分:1)

不,对你没有区别。只需使用U() : p() {}

  

[注意:通常,必须使用显式析构函数调用和放置新运算符来更改活动   工会成员。 - 结束说明]

     

[示例:考虑具有非静态数据的联合类型U的对象u   m类型的成员Mn类型的N。如果M有一个非平凡的析构函数,N有一个非平凡的构造函数   (例如,如果它们声明或继承虚函数),u的活动成员可以使用析构函数和放置new运算符从m安全地切换到n,如下所示:

u.m.~M();
new (&u.n) N;
     

- 结束示例]

即。你的第一个变种是正确的。


该标准还说:

  

联合的最多一个非静态数据成员可能有一个大括号或等于初始值。

就个人而言,我希望以下内容是正确的:

union U {
    int z;
    double w;
    Point p {1,2};
};

#include <iostream>
int main () {
    U u;
    std::cout << u.p.x_ << ":" << u.p.y_ << std::endl;
}

我希望输出1:2,但是使用g ++ 4.8.1我得到了垃圾值。当我尝试

union U {
    int z;
    double w;
    Point p = Point(1,2);
};

我也得到垃圾值。我不确定这是否是编译器错误。

修改brace-or-equal-Initializer in unions

答案 1 :(得分:1)

您可以在 ctor-initializer-list 中最多初始化一个union的一个成员。 union是一个类,因此[class.base.init](C ++11§12.6.2)中成员初始值设定项的规则适用于具有class-key struct或{{的类的规则。 1}}。 12.6.2 / 8中说明了一个明显的例外:“尝试初始化一个联盟的多个非静态数据成员会导致程序格式不正确。”