您可以在运行时将结构的void指针强制转换为特定的结构类型吗?

时间:2013-03-19 13:58:28

标签: c pointers struct void

我有一个像这样定义的结构:

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中指定一个类型并在运行时强制转换变量?

1 个答案:

答案 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字段,依此类推。