关于工会我仍然不了解的问题.我已经阅读了很多他们的用途,并且大部分都可以看到它们如何有用并理解它们.我已经看到他们可以提供原始的“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;
我无法理解的是,与那些事件类型共存的“类型”成员怎么样?这些不是每个只允许一次存在一个,因为它们占据相同的记忆区域吗?工会不会随时存在,无论是类型还是其中一个事件?
据我所知,每个事件实际上都是一个带有类型成员的结构,例如:
// SDL_MouseButtonEvent typedef struct{ Uint8 type; Uint8 button; Uint8 state; Uint16 x,y; } SDL_MouseButtonEvent;
这怎么有意义?这是否以某种方式允许联合的类型成员表示联合当前的任何结构的类型?当一个联盟的每个成员除了一个结构并且每个结构包含那个成员时,会发生这种奇怪的效果吗?
你可以在不知道对象是哪个结构的情况下访问struct成员吗?
谢谢!
解决方法
如果每个事件类型都有一个Uint8作为其第一个数据成员,那么union的类型成员只是一个方便.
联合的一般规则是您只能使用您编写的最后一个数据成员访问联合中的数据.因此,如果您上次写入活动状态,则无法从密钥读取.
此规则的一个例外是,如果联合的多个成员共享相同的前缀(如果它们的第一个数据成员相同),则可以通过共享前缀的联合的任何数据成员访问该前缀.所以,在这里,你可以引用active.type或key.type,无论union的哪个数据成员是活动的,它都可以工作.
SDL_Event的类型成员只是一个方便的快捷方式,允许您访问该类型字段,而不必将其限定为event_object.active.type或event_object.key.type.你可以使用event_object.type.