为什么结构中的命名联合会覆盖其他结构成员?

时间:2013-10-07 10:52:03

标签: c++ struct unions

struct TestStruct
{   
    int a;
    int b;

    union
    {
        char c[2];
        int d;
    };
};

TestStruct instance;

如果我这样做

instance.a = 100; 
instance.b = 200; 
instance.d = 300;
一切都很好。

但是,如果我给工会一个名字:

struct TestStruct
{   
    int a;
    int b;

    union ZZZ // Note here!!
    {
        char c[2];
        int d;
    };
};

TestStruct instance;

我又做了同样的事情:

instance.a = 100;
instance.b = 200;
instance.ZZZ::d = 300;

然后

instance.ZZZ::d = 300;

instance.a覆盖为300,为什么?!

此外,如果它具有名称,我在调试器监视列表中看不到联合成员。

我正在使用Visual Studio 2008。

1 个答案:

答案 0 :(得分:8)

当您为联盟命名时,类中不再有与d对应的数据成员,因此instance.ZZZ::d = 300;没有任何意义。 (使用VS2012,我得到“错误C2039:'ZZZ':不是'TestStruct'的成员”)

要拥有联盟类型的成员,您必须为其命名。

struct TestStruct
{   
    int a;
    int b;

    union ZZZ // Note here!!
    {
        char c[2];
        int d;
    } z;
};

instance.a = 100;
instance.b = 200;
instance.z.d = 300;

C ++对“匿名联盟”有一个特殊规则,其中union { member-specification };形式的未命名联合类型也会创建一个未命名的对象。联合成员的名称被注入封闭范围并访问未命名对象的成员。

当你没有在班级中命名联合类型时,这就是你得到的。但是只要你给类型命名,联合就不再匹配那个特殊规则了,并且在类中不再有一个未命名的联盟成员;然后,您必须通过命名成员变量来正常添加联合数据成员。