我有一个像这样定义的结构:
struct GameState {
int score;
int moves;
bool won;
void *metadata;
};
typedef struct GameState GameState;
元数据指针将指向运行时决定的另一个类型的结构。例如,它可能是:
struct KlondikeMetadata{
bool draw3;
int drawcount;
};
typedef struct KlondikeMetadata KlondikeMetadata;
或者也许:
struct FreeCellMetadata{
int reserveCells;
};
typedef struct FreeCellMetadata FreeCellMetadata;
使用的实际元数据结构取决于用户正在玩的游戏。 99%的时间这不是问题,因为我知道用户正在玩什么游戏。但是,有些情况下我不会(也不可能)知道这一点。
我的问题是,有没有办法在运行时确定或指定正确的元数据类型?
例如,如果我可以向GameState结构添加一个属性,指示元数据值是KlondikeMetadata类型并使用它来将元数据转换为该类型,我想我会是金色的。有没有办法做到这一点?有没有办法在C中指定一个类型并在运行时强制转换变量?
答案 0 :(得分:7)
你将不得不自己编码。
最简单的解决方案是声明枚举:
typedef enum {
GameType_Klondike,
GameType_FreeCell,
} GameType;
然后在指针之前添加该类型的字段:
GameType game_type;
void *metadata;
当然,这意味着您在初始化game_type
时必须设置 metadata
字段,以便记住类型。
您也可以采用面向对象的方式,让GameType
成为元数据的一部分:
struct Metadata {
GameType gametype;
};
struct FreeCellMetadata {
struct Metadata meta;
/* rest of fields here */
};
struct KlondikeMetadata {
struct Metadata meta;
/* rest of fields here */
};
然后,您可以将void *
转换为struct Metadata *
,并在将指针转换为正确类型之前检查gametype
字段。
对于奖励积分,请使用工会:
struct Metadata {
GameType type;
union {
struct KlondikeMetadata klondike;
struct FreecellMetadata freecellL;
} game;
};
同样,当然这需要您维护数据,即初始化struct KlondikeMetadata
时,您必须记住设置其gametype
字段,依此类推。