我有一个关于工会的问题,我仍然不理解。我读过很多关于它们的用法,大多数情况下,我可以看到它们是如何有用的,并理解它们。我已经看到它们可以提供一个原始的"C风格“多态性。我在几个网站上看到的例子是SDL的事件联盟:
typedef union {
Uint8 type;
SDL_ActiveEvent active;
SDL_KeyboardEvent key;
SDL_MouseMotionEvent motion;
SDL_MouseButtonEvent button;
SDL_JoyAxisEvent jaxis;
SDL_JoyBallEvent jball;
SDL_JoyHatEvent jhat;
SDL_JoyButtonEvent jbutton;
SDL_ResizeEvent resize;
SDL_ExposeEvent expose;
SDL_QuitEvent quit;
SDL_UserEvent user;
SDL_SysWMEvent syswm;
} SDL_Event;我不明白的是,怎么会有一个"type“成员与事件类型共存呢?因为它们占用相同的内存区域,所以它们不是每次只允许存在一个吗?联合不会在任何时候作为一种类型或一个事件而存在吗?
我知道每个事件实际上都是一个带有类型成员的结构,例如:
// SDL_MouseButtonEvent
typedef struct{
Uint8 type;
Uint8 button;
Uint8 state;
Uint16 x, y;
} SDL_MouseButtonEvent;这怎么可能有意义呢?这是否以某种方式允许联合的类型成员表示联合当前所属的任何结构的类型?当联合的每个成员都是一个结构,并且每个结构都包含一个成员时,会发生某种奇怪的效果吗?
你能在不知道对象是哪个结构的情况下访问结构成员吗?
谢谢!
发布于 2011-02-09 08:18:34
如果每个事件类型都有一个Uint8作为其第一个数据成员,那么union的type成员只是为了方便起见。
联合的一般规则是,您只能使用写入的最后一个数据成员访问联合中的数据。因此,如果您最后一次写入active,则下一次不能从key读取。
此规则的一个例外是,如果联合的多个成员共享相同的前缀(如果它们的第一个数据成员相同),则可以通过共享前缀的联合的任何数据成员访问该前缀。因此,在这里,您可以引用active.type或key.type,而不管联合的哪个数据成员是活动的,它都可以工作。
SDL_Event type成员只是一个方便的快捷方式,它允许您访问type字段,而不必将其限定为event_object.active.type或event_object.key.type。您可以只使用event_object.type。
发布于 2011-02-09 08:21:05
让我们看一下联合是如何在内存中布局的:
Address: Uint8 MouseButtonEvent KeyboardEvent
x+0x0 type type type
x+0x1 - button ?
x+0x2 - state ?
...碰巧所有的联合成员都排成一列,所以不管它是什么类型,作为Uint8访问联合都会产生事件的实际类型。
发布于 2011-02-09 08:19:37
如果这些struct的前几个字节中的每一个都是它们自己的类型字段,这意味着当联合包含其中一个对象时,联合的前几个字节与SDL_xyz结构的前几个字节是相同的-即类型字段。
联合并不包含两者,它只包含SDL对象,该对象的第一个成员恰好在类型、大小和位置上与' type‘字段重合。
https://stackoverflow.com/questions/4940064
复制相似问题