【问题标题】:Resolve circular dependency of type definitions解决类型定义的循环依赖
【发布时间】:2011-12-07 18:33:22
【问题描述】:

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 附加到typedefs,或将_s(或Struct)附加到structs?大概是口味问题。然后,您是否希望将前向定义作为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;

【问题讨论】:

    标签: c struct typedef


    【解决方案1】:

    前向声明:

    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;
    

    【讨论】:

      【解决方案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];
      };
      

      【讨论】:

        【解决方案3】:

        您需要转发声明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];
        };
        

        【讨论】:

          猜你喜欢
          • 2018-08-24
          • 2020-11-12
          • 1970-01-01
          • 2013-04-23
          • 1970-01-01
          相关资源
          最近更新 更多