C++ 什么';使用只有一个成员的工会的目的是什么?

C++ 什么';使用只有一个成员的工会的目的是什么?,c++,c++14,unions,C++,C++14,Unions,当我阅读时,我注意到有一个名为tx\u-side的联合结构,它只有一个成员。这是处理某个问题的技巧吗 仅供参考,我将tx_侧结构粘贴到下面: union tx_side { tx_side() {} ~tx_side() {} void init() { new (&a) aa; } struct aa { std::deque<work_item*> pending_fifo; } a; } _tx; union-t

当我阅读时,我注意到有一个名为
tx\u-side
的联合结构,它只有一个成员。这是处理某个问题的技巧吗

仅供参考,我将
tx_侧
结构粘贴到下面:

union tx_side {
    tx_side() {}
    ~tx_side() {}
    void init() { new (&a) aa; }
    struct aa {
        std::deque<work_item*> pending_fifo;
    } a;
} _tx;
union-tx\u侧{
tx_侧(){}
~tx_-side(){}
void init(){new(&a)aa;}
结构aa{
std::deque待定的fifo;
}a;
}_tx;

因为
tx\u-side
是一个联合体,
tx\u-side()
不会自动初始化/构造
a
~tx\u-side()
不会自动销毁它。 这允许通过放置新的和手动析构函数调用(穷人的
std::optional
),对
a
挂起的(fifo
)的生命周期进行细粒度控制

下面是一个例子:

#include <iostream>

struct A
{
    A() {std::cout << "A()\n";}
    ~A() {std::cout << "~A()\n";}
};

union B
{
    A a;
    B() {}
    ~B() {}
};

int main()
{
    B b;
}
#包括
结构A
{

(){std::cout简单地说,除非显式地分配/初始化一个值,单成员联合不会初始化分配的内存。这个功能可以通过c++17中的
std::optional
来实现。

的潜在重复。@MaxLanghof这个问题和相应的答案没有提到目的使用这样的联合结构是非常困难的。你有使用这个成员的例子吗?这就是为什么我没有实际使用我的约束性接近投票。但是我不确定你对你的问题的答案的期望是什么,而不是直接从那边的答案。大概使用
union
而不是
struct
的目的是为了这是一个相当模糊的技术,除非代码的原始作者出现,否则我不确定有人能给你一个权威的答案,他们希望用这个来解决哪个问题(如果有的话)。我最好的猜测是,联合是用来延迟建设的(在这种情况下这有点毫无意义)或防止破坏(导致内存泄漏)关于挂起的fifo。但是很难说没有用法的例子。@daoliker不一定是随机的,但你无法预测。与任何其他未初始化的变量一样。你不能假设它是随机的;据你所知,它可能保存着你之前要求他们输入的用户密码。@daoliker:前面的评论太乐观了。随机字节w应该有0-255范围内的值,但如果将未初始化的字节读入
int
中,可能会得到
0xcccc
。读取未初始化的数据是未定义的行为,可能发生的情况是编译器干脆放弃尝试。这不仅仅是理论。Debian犯了这个错误,并破坏了他们的OpenSSL实现他们有一些真正的随机字节,添加了一个未初始化的变量,编译器说“结果是未定义的,所以它可能是零”.Zero显然不再是随机的了。@MSalters:你有这一说法的来源吗?因为我能找到的证据表明事情并不是这样的:删除它的不是编译器,而是开发人员。老实说,如果有编译器编写者做出了如此糟糕的决定,我会感到惊讶。(请参阅)@杰凯德利:确切的说法是什么?你确实有一个很好的链接,似乎我把故事颠倒过来了。OpenSSL的逻辑错误,使用了一个未初始化的变量,使得编译器可以合法地假设任何结果。Debian正确地发现了这一点,但打破了修复。至于“编译器做出如此糟糕的决定”;他们不会做出这样的决定。未定义的行为是错误的决定。优化器被设计为在正确的代码上运行。例如,GCC主动假定没有签名溢出。假定“没有未初始化的数据”同样合理;它可以用来消除不可能的代码路径。@JackAidley我遇到了与@MSalters在我自己的代码中提到的问题类似的问题;我错误地假设未初始化的变量为空,并且在随后的
!=0
比较结果为真时感到困惑。此后,我添加了编译器标志来处理未初始化的变量将变量序列化为错误,以确保我不会再次落入该陷阱。这是一个误导性的答案。只有一个成员的联合将具有与该成员相同的大小。在初始化该成员之前,不会初始化该内存。