如果我有课:
class Odp
{
int i;
int b;
union
{
long f;
struct
{
WCHAR* pwszFoo;
HRESULT hr;
};
};
}
Union意味着,在列出的所有值中,它一次只能接受其中一个值?在访问这些变量方面,它如何工作?我如何直接访问hr
?如果我设置hr
,如果我尝试访问f
会怎样?
答案 0 :(得分: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库以外的任何东西,那就错了。
答案 1 :(得分:4)
每次设置(写入)联盟成员时,您基本上都会将其设置为“活动”。您只能阅读当前活动的联盟成员。这意味着您有责任以某种方式记住每个时刻哪个成员活跃。
尝试访问联合的非活动成员会导致未定义的行为。
请记住,您的代码无效C ++。在C ++中没有“匿名结构”这样的东西。您的结构成员必须具有名称。如果您的编译器接受它,它只是您的特定编译器支持的非标准扩展。
答案 2 :(得分:2)
是的,使用union
,在任何给定时间,相同的内存位置将用于表示单个成员。因此,如果您有一个union实例并设置hr
的值,那么如果您尝试读取f
的值,则会出现垃圾。
尝试使用以下内容访问hr
:
union a;
a.hr = NULL;
答案 3 :(得分:1)
这只意味着您可以访问与long或struct相同的内存。
访问hr
:
Odp o1;
o1.hr;
答案 4 :(得分:0)
尝试访问“f”会给你一些结果。它可能代表联盟的其他成员作为“f”的数据类型,即在这种情况下,您可能会读取表示为“长”数据类型的“pwszFoo”的部分或全部内容。一般概念很简单 - 联盟成员在内存中共享相同的位置。