在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() {}
答案 0 :(得分:1)
不,对你没有区别。只需使用 U() : p() {}
。
[注意:通常,必须使用显式析构函数调用和放置新运算符来更改活动 工会成员。 - 结束说明]
[示例:考虑具有非静态数据的联合类型U的对象u
m
类型的成员M
和n
类型的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);
};
我也得到垃圾值。我不确定这是否是编译器错误。
答案 1 :(得分:1)
您可以在 ctor-initializer-list 中最多初始化一个union的一个成员。 union是一个类,因此[class.base.init](C ++11§12.6.2)中成员初始值设定项的规则适用于具有class-key struct
或{{的类的规则。 1}}。 12.6.2 / 8中说明了一个明显的例外:“尝试初始化一个联盟的多个非静态数据成员会导致程序格式不正确。”