2011-12-07 30 views
1

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

更新

謝謝 - 在同一時間三個相當於收起答案,我可以選擇其中的任何一個。

所以,要恢復,在解決這個問題時你有什麼選擇?首先,命名約定 - 附加_ttypedef s或_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; 

回答

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]; 
}; 
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]; 
}; 
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;