解决类型定义的循环依赖关系

时间:2011-12-07 18:33:23

标签: c struct typedef

C tutorial之后,我遇到了一个我不知道如何解决的类型依赖。到目前为止,我们有这个:

typedef long SetStringPtr( char * );
typedef long GetStringPtr( char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

typedef struct {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
} IExample;

没问题。现在,它正在改变以包含一个THIS指针:

typedef long SetStringPtr( IExample *, char * );
typedef long GetStringPtr( IExample *, char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

typedef struct {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
} IExample;

这些定义以循环方式相互依赖。 cl.exe编译器显示了很多语法错误,因为当我使用IExample时它还没有被声明。我该如何解决这个问题?

使用cl.exe /W4进行编译。

更新

谢谢 - 同时有三个无可比拟的答案,我可以选择其中任何一个。

因此,要恢复,在解决此问题时您需要做出哪些选择?首先,命名约定 - 将_t追加到typedef,或_s(或Struct)追加到struct s?可能是品味问题。然后,您是否希望将前向定义作为typedef的一部分或作为struct的一部分。可能也是品味问题。这是另一种形式的问题和三种解决方法:

/* won't compile */
typedef struct {
        B * b;
        C * c;
} A;

typedef struct {
        A * a;
        C * c;
} B;

typedef struct {
        A * a;
        B * b;
} C;

第一个解决方案:

struct B_s;
struct C_s;

typedef struct {
        struct B_s * b; // typedef not available yet
        struct C_s * c; // ditto
} A;

typedef struct {
        A * a;
        struct C_s * c; // ditto
} B;

typedef struct {
        A * a;
        B * b;
} C;

第二个解决方案:

typedef struct B_s B;
typedef struct C_s C;

typedef struct {
        B * b;
        C * c;
} A;

// typedef struct ... B => change to:
struct {
        A * a;
        C * c;
} B_s;

// typedef struct ... C => change to:
struct {
        A * a;
        B * b;
} C_s;

第三个(也是最对称的)解决方案:

struct A_s;
struct B_s;
struct C_s;

typedef struct A_s A;
typedef struct B_s B;
typedef struct C_s C;

struct {
        B * b;
        C * c;
} A_s;

struct {
        A * a;
        C * c;
} B_s;

struct {
        A * a;
        B * b;
} C_s;

3 个答案:

答案 0 :(得分:3)

前向声明:

struct IExampleStruct;   /* <--- !! */

typedef long SetStringPtr( struct IExampleStruct *, char * );
typedef long GetStringPtr( struct IExampleStruct *, char *, long );

/* ... */

typedef struct IExampleStruct {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
} IExample;

答案 1 :(得分:2)

typedef struct IExample_s IExample;

typedef long SetStringPtr( IExample *, char * );
typedef long GetStringPtr( IExample *, char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

struct IExample_s {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
};

答案 2 :(得分:1)

您需要转发声明IExample结构。

//Forward Declare here
typedef struct IExample IExample_t;

typedef long SetStringPtr( IExample_t *, char * );
typedef long GetStringPtr( IExample_t *, char *, long );

typedef struct {
    SetStringPtr * SetString;
    GetStringPtr * GetString;
} IExampleVtbl;

struct IExample {
    const IExampleVtbl * lpVtbl;
    DWORD count;
    char  buffer[80];
};