处理C或C ++循环依赖的最佳方法是什么?

时间:2017-12-02 10:43:07

标签: c++ c header-files typedef

在C中,当我需要时:

档案a.h

#ifndef A_H
#define A_H

#include "b.h"

typedef struct A { B* second_struct; } A;

#endif /* !A_H */

档案b.h

#ifndef B_H
#define B_H

#include "a.h"

typedef struct B { A* first_struct; } B;

#endif /* !B_H */

我冒昧地以这种方式重新排列:

typedef struct A A;

#ifndef A_H
...

(同样适用于b.h。)

我在标题的第一行中使用class A;在C ++中做了完全相同的事情。

然而,有人告诉我这是一个不好的做法,在C中,因为typedef应该创建另一种类型,并且可能与之前的同一typedef冲突,以防多次包含。

他还告诉我,由于这些原因,没有一个声明应该在头球防守之外。

所以,他建议我在typedef struct A A;声明前b.hstruct B(反之亦然),因为这是我需要的地方。

我的问题是:

在这种情况下,typedef .. A;b.h丢失是不是很危险?

更一般地说,处理这种依赖性的最佳做法是什么?

1 个答案:

答案 0 :(得分:0)

处理这类依赖关系的最佳做法通常是避免它们。但这并不总是可行的。

我这样做:

A.H

#ifndef B_H
#define B_H

#include "a.h"

// Forward decls
struct A;

typedef struct B { struct A* first_struct; } B;

#endif /* !B_H */

b.h

struct A*

在C和C ++中都有效。

前向声明应尽可能简单,因此应避免使用typedef,这在本例中很简单。这只意味着您必须在B的定义中使用A*而不是#include "a.h"

关于包含守卫之外的typedef:这绝对不是标准做法。

首先struct A确保struct A的前瞻性声明存在,这听起来很诱人。问题是{{1}}可能是不完整的类型并不明显。

前瞻性声明也是对未来读者的警告,他们可能正在处理不完整的类型。