C++联合、结构、成员类型

mbjcgjjk  于 2022-11-27  发布在  其他
关注(0)|答案(6)|浏览(173)

如果我有一个类:

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

}

Union意味着,在列出的所有值中,它一次只能取其中的一个值?如何访问这些变量?如何直接访问hr?如果我设置了hr,如果我试图访问f,会发生什么?

atmip9wb

atmip9wb1#

这在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库之外的任何东西,那么就有问题了。

p3rjfoxz

p3rjfoxz2#

每次设置(写入)一个联合的成员时,实际上是将其设置为“活动”。您只允许读取联合中当前活动的成员。这意味着您有责任以某种方式记住在每个时刻哪个成员是活动的。
试图访问联合的非活动成员会导致未定义的行为。
还要记住,你的代码不是有效的C++。在C++中没有“匿名结构”这样的东西。你的结构成员必须有一个名字。如果你的编译器接受它,它只是一个特定编译器支持的非标准扩展。

slmsl1lt

slmsl1lt3#

对,对于union,相同的内存位置将用于在任何给定时间表示单个成员。因此,如果你有一个联合体的示例,并设置了hr的值,如果你随后试图读取f的值,你将得到垃圾。
尝试使用以下命令访问hr

union a;
a.hr = NULL;
gcmastyq

gcmastyq4#

它只是意味着你可以访问与long或struct相同的内存。
要访问hr,请执行以下操作:

Odp o1;
o1.hr;

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

r7knjye2

r7knjye25#

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

gtlvzcf8

gtlvzcf86#

联合将为最大类型分配足够的内存(thing)。所以你可能有很多类型的对象,它们都有很大的内存空间,你一次只能把其中的一个传递到代码中的其他地方。Union允许你这样做。这比传递一个void指针更高级。无论是哪种情况,你都需要设计一种方法来了解Union示例中存储了什么。下面的代码是一种简单的方法,它将Union Package 在一个结构中。该结构定义了一个枚举来标识Union所使用的项,并提供了一个存储枚举类型的位置。

union UnionItem {
      int a;
      float b;
      double c;
   };

   struct UnionObj {
      enum Type{
         I, F, D
      };
      Type t;
      UnionItem item;
   };

   UnionObj o;
   o.item.b = 2.3f;
   o.t = UnionObj::F;

   // Usually the UnionObj would be passed to other functions or methods.

   switch (o.t) {
   case UnionObj::I:
      cout << o.item.a;
      break;
   case UnionObj::F:
      cout << o.item.b;
      break;
   case UnionObj::D:
      cout << o.item.c;
      break;
   default:
      cout << "Something wrong!";
   }

相关问题