How to initialize a non-POD member in Union

非 Y 不嫁゛ 提交于 2019-12-11 10:29:15

问题


In c++11, Union supports non-POD member. I want to initialize a non-POD member in the constructor.

On wikipedia c++11 page, it uses a placement 'new' to initialize a non-POD member.

#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.
};

I am wondering is there any difference if I use ctor-initializer-list instead of placement 'new'?

U() : p() {}

回答1:


No, no difference for you. Just use U() : p() {}.

[ Note: In general, one must use explicit destructor calls and placement new operators to change the active member of a union. — end note ]

[ Example: Consider an object u of a union type U having non-static data members m of type M and n of type N. If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement new operator as follows:

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

— end example ]

I.e. your first variant is correct.


The standard also says:

At most one non-static data member of a union may have a brace-or-equal-initializer.

Personally, I would expect the following to be correct:

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;
}

I would expect the output 1:2, but with g++ 4.8.1 I get garbage values. When I try

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

I get garbage values, too. I am not sure if this is a compiler bug.

edit: brace-or-equal-Initializer in unions




回答2:


You are free to initialize at most one member of a union in the ctor-initializer-list. A union is a class, so the rules for member initializers in [class.base.init] (C++11 §12.6.2) apply just as they do to classes with the class-key struct or class. One obvious exception is stated in 12.6.2/8: "An attempt to initialize more than one non-static data member of a union renders the program ill-formed."



来源:https://stackoverflow.com/questions/23004941/how-to-initialize-a-non-pod-member-in-union

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!