【发布时间】:2011-04-05 07:35:25
【问题描述】:
我收集 unrestricted unions 作为 C++11 中提出的功能之一。谁能解释一下这背后的语义及其提供的优势?
【问题讨论】:
我收集 unrestricted unions 作为 C++11 中提出的功能之一。谁能解释一下这背后的语义及其提供的优势?
【问题讨论】:
维基百科上有解释:http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions
在询问 C++0x 功能说明之前先搜索那里。
不受限制的联合
在标准 C++ 中 对什么类型有限制 of 对象可以是联合的成员。 例如,联合不能包含任何 定义非平凡的对象 构造函数。 C++0x 会缓解一些 这些限制,允许工会 用于更多类型,他们 以前不允许使用 [6]这是一个简单的例子 C++0x 中允许的联合:
//for placement new #include <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++; point has a non-trivial constructor. // However, this is legal in C++0x. U() { new( &p ) Point(); } // No nontrivial member functions are //implicitly defined for a union; // if required they are instead deleted // to force a manual definition. };这些更改不会破坏任何 现有的代码,因为它们只是放松 现行规则。
【讨论】:
它只不过是我们一直拥有的旧联合,一个对象一次包含一个成员,类型各异。
更改只是现在允许您在联合中存储非 POD 类型。但是,您将负责显式构造和销毁该成员。
来自 N3242:
[ 示例:考虑具有非静态数据的联合类型 U 的对象 u M 类型的成员 m 和 N 类型的 n。如果 M 有一个非平凡的析构函数并且 N 有一个非平凡的构造函数 (例如,如果他们声明或继承虚函数), u 的活动成员可以安全地切换 从 m 到 n 使用析构函数和放置 new 运算符如下:
嗯~M();
新 (&u.n) N;
—结束示例]
不是一个广泛有用的功能,IMO。
【讨论】:
它扩展了联合以允许任何类型,而不仅仅是“普通旧数据”,让您可以更灵活地在同一位置存储不同类型的数据,而无需求助于手动指针黑客。
您为此付出的代价是您必须仔细记账。使用普通的旧数据联合分配足以更改“当前类型”,读取错误的类型可能会导致数据乱码,但仅此而已。对于非普通的旧数据联合,您必须跟踪当前类型并手动调用正确的构造函数和析构函数以更改当前类型并在销毁整个联合时正确清理内容。如果你尝试读取或写入 wring 类型,很可能会发生不好的事情
【讨论】: