【问题标题】:Avoiding Circular Dependency in C header files避免 C 头文件中的循环依赖
【发布时间】:2013-11-01 22:48:44
【问题描述】:
 header1.h   
        -----------------
        struct A{
        int a;
        B *b;
        };

    header2.h  
    -------------------
    #include"header1.h"

    typedef struct b{
    int aa;
    char bb;
    int cc;
    }B;

    main.c  
    --------------------
    #include<header2.h>

    main(){

    struct A *ace;
    ace = malloc(sizeof(struct A));
    ace->b = malloc(sizeof(B));
    }

问题:基本上,header1.h 需要使用 header2.h 中定义的结构。

困境:由于 header2.h 包含 header1.h,如果我在 header1.h 中包含 header2.h,我将引入循环依赖。

一些解决方案:解决问题的一种方法是使用 void 指针,但还有其他方法吗?我尝试向前声明它,但它说“重新定义 typedef”。

【问题讨论】:

  • 将include guards 添加到您的标题中。
  • 这不会解决你的问题,但应该是一个风格提示:在包含语句上保持一致 - 不要在非系统提供的标题上使用 &lt; &gt;,但只使用 " " - 总是。

标签: c header circular-dependency


【解决方案1】:

所以你遇到的问题是指针

B *b;

在结构 A 中。因为这是一个指针,所以只要你告诉它这是一个不完整的类型就可以了。

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

或者你可以使用原型形式:

struct B;
typedef struct a {
    int a;
    B *b;
};

编译器只是想知道指针指向什么类型的东西——就在这里,它实际上并不关心它看起来更详细的样子,直到你第一次开始尝试取消引用它。

【讨论】:

  • 所以它基本上是一个空指针。但它以后会自行解决吗?或者每当我使用它时,我必须施放它?
  • struct B 基本上是 B 的完整声明的原型,它告诉编译器创建指向结构 B 的指针所需知道的最小值。创建指针不会需要知道类的内部是什么样子,它被称为什么以及它是一个结构(而不​​是联合或 typedef)。
【解决方案2】:

您可以通过像这样包装头文件来轻松防止头文件被多次包含

#ifndef FOO_H_ /* include guard */
#define FOO_H_

/* * * * * insert foo.h here * * * * */

#endif /* FOO_H_ */

【讨论】:

  • 不要使用前导下划线后跟大写字母,因为它们在许多系统/设置中都是保留的。
【解决方案3】:

我建议在这种情况下使用前向声明,因为 struct B 仅作为指针出现并且不要尝试访问 struct B 的任何成员。编译器会很高兴,我假设只有源代码可以访问这些成员。

header1.h:

struct B;

struct A{
    int a;
    B *b;   
}   

【讨论】:

    猜你喜欢
    • 2011-06-16
    • 2013-02-06
    • 1970-01-01
    • 2011-07-11
    • 2015-07-25
    • 2012-02-15
    • 1970-01-01
    相关资源
    最近更新 更多