6

如果我有一堂课:

class Odp
{
    int i;
    int b;
    union
    {
         long f;
         struct
         {
               WCHAR* pwszFoo;
               HRESULT hr;
         };
    };

}

联合意味着,在列出的所有值中,它一次只能采用其中一个值?这在访问这些变量方面是如何工作的?我将如何hr直接访问?如果我设置hr,如果我尝试访问会发生什么f

4

5 回答 5

8

这是 C++ 标准中一个非常令人担忧的领域 - 基本上是一个联合实例,根据标准只能在任何时候被视为包含一个“活动”成员 - 最后一个写入它的成员。所以:

union U {
   int a;
   char c;
};

然后:

U u;
u.a = 1;
int n = u.a;
u.c = 2;
char c = u.c;

可以,但是:

U u;
u.a = 1;
char c = u.c;

不是。但是,现有大量代码表明两者都可以。并且在任何情况下都不会为“无效”访问引发异常。C++ 语言非常谨慎地使用异常 (!)。

基本上,如果您发现自己在 C++ 代码中使用联合来处理除 C 库之外的任何内容,那么就出了问题。

于 2010-06-18T17:39:19.117 回答
4

每次您设置(写入)工会成员时,您基本上都会使其“活跃”。您只能阅读当前活跃的工会成员。这意味着您有责任以某种方式记住在每个时刻哪个成员处于活动状态。

尝试访问联合的非活动成员会导致未定义的行为。

还要记住,您的代码不是有效的 C++。C++ 中没有“匿名结构”这样的东西。您的结构成员必须有一个名称。如果您的编译器接受它,它只是您的特定编译器支持的非标准扩展。

于 2010-06-18T17:28:53.840 回答
2

对,union在任何给定时间,将使用相同的内存位置来表示单个成员。因此,如果您有联合的实例并设置 的值hr,那么如果您尝试读取 的值,则会得到垃圾f

尝试使用以下访问hr

union a;
a.hr = NULL;
于 2010-06-18T17:26:39.920 回答
1

这只是意味着您可以访问与 long 或 struct 相同的内存。

访问hr

Odp o1;
o1.hr;

有趣的链接:http ://www.cplusplus.com/forum/general/18816/

于 2010-06-18T17:24:38.063 回答
0

尝试访问“f”会给你一些结果。它可能会将联合的其他成员表示为“f”的数据类型,即在这种情况下,您可能会读取表示为“long”数据类型的“pwszFoo”的部分或全部内容。一般概念很简单——联合成员在内存中共享相同的位置。

于 2016-09-15T09:25:44.287 回答