【发布时间】:2013-05-21 16:48:24
【问题描述】:
我对无限制工会及其在实践中的应用有一些疑问。 假设我有以下代码:
struct MyStruct
{
MyStruct(const std::vector<int>& a) : array(a), type(ARRAY)
{}
MyStruct(bool b) : boolean(b), type(BOOL)
{}
MyStruct(const MyStruct& ms) : type(ms.type)
{
if (type == ARRAY)
new (&array) std::vector<int>(ms.array);
else
boolean = ms.boolean;
}
MyStruct& operator=(const MyStruct& ms)
{
if (&ms != this) {
if (type == ARRAY)
array.~vector<int>(); // EDIT(2)
if (ms.type == ARRAY)
new (&array) std::vector<int>(ms.array);
else
boolean = ms.boolean;
type = ms.type;
}
return *this;
}
~MyStruct()
{
if (type == ARRAY)
array.~vector<int>();
}
union {
std::vector<int> array;
bool boolean;
};
enum {ARRAY, BOOL} type;
};
- 此代码有效吗 :) ?
- 是否有必要在每次使用布尔值时显式调用向量析构函数(如此处所述http://cpp11standard.blogspot.com/2012/11/c11-standard-explained-1-unrestricted.html)
- 为什么需要一个新的展示位置,而不是仅仅执行“array = ms.array”之类的操作?
编辑:
- 是的,它可以编译
- “在匿名联合中声明的成员实际上是包含类的成员,并且可以在包含类的构造函数中初始化。” (C++11 anonymous union with non-trivial members)
- 按照建议添加显式析构函数会导致使用 g++ 4.8 / clang 4.2 的 SIGSEV
【问题讨论】:
-
联合有时被用来颠覆类型系统——类型双关语。在这种情况下,您不会在读/写
bool之前破坏vector,但标准没有(也不能)定义这意味着什么——效果取决于平台的细节。无论如何,您可能不会使用vector来执行此操作 - 也许使用 char 数组来查看字节。如果您没有双关语,则只能读出最后写入的内容(否则会导致数据损坏),并且您必须在写入其他内容之前删除(破坏)联合中已经存在的任何内容(否则会导致内存/资源泄漏) .