5

至于从事一个更大的项目,我想加入一些自己的类型(例如myType)。“冲进来”的方法是将这些类型定义放入标题中(比如说myType.h),以及处理这些类型的一堆函数。

如果我在某处使用新类型,我会将其包含myType.h到我的源文件中。美好的。

但是,如果我想在某处使用新类型作为函数签名中的参数,我需要将 包含myType.h到包含该函数的模块的标头中。使用一个或另一个 typedef,这对我来说似乎没问题,但是我拥有的类型越多,我需要的头文件中包含的内容就越多,可能包括更多的头文件,同时使用包含其他自己类型的类型。这导致了我所说的“依赖地狱”。

有没有一种聪明、时尚、最佳实践的方法来解决这个困境?

我知道将这些类型作为 void-pointer 传递的可能性,将它们强制转换回函数内部,但随后我失去了编译器的重要类型检查。

此外,extern这里被认为是最糟糕的做法..

编辑:

详细地:

myType.h

#include "otherType.h"

typedef struct {
  char Name[32];
  int Size;
  otherType someType;
} myType;

processSomeHow(myType _myType, int NewSize);

otherType.h

#define SOME_CONST 32

typedef struct { [...] } otherType;

someModule.h

#include "myType.h"

int specialProcessSomeHow(myType _myType);

someModule.c

int specialProcessSomeHow(myType _myType)
{
  int Size = 64;
  return(processSomeHow(_myType, Size));
}

现在我otherType.h间接包含到. 甚至更糟糕的是,我将它包含到每个模块中,someModule.h包括 someModule.h现在我SOME_CONST到处都有,很难弄清楚它来自哪里。我必须维护两个包含树。

4

3 回答 3

1

就像在 gtk 库中一样,您可以使用一个头文件并根据需要对其进行拆分。

type.h
- myType.h
-- someType.h
- otherType.h
- List item

并在您的 CONST 问题上:如果您只需要一个 c.file。不要在 HeaderFile 中使用它们。您可以将它们命名为“MY_TYPE_SOME_CONST”或“OTHER_TYPE_SOME_CONST”;

//编辑:

说清楚:只需添加“this.h”文件并命名。

#ifndef TYPE_H_
#define TYPE_H_

#include myType.h
#include someType.h
#include otherType.h

#endif /* TYPE_H_ */

现在您可以为每个需要您的类型的文件使用“#include this.h”。(this.h 不是真实的,将其命名为独特的名称)

于 2013-03-25T10:54:58.723 回答
0

您可以(并且可能应该)为您的自定义类型使用前向声明。在此处查看详细信息:typedef stuct with forward declaration in C

您的接口(标头)应该具有不完整的类型(即指向您的自定义类型的指针),并且在源代码(c 文件)中,您应该包含My_Type.h.

于 2013-03-25T09:30:32.277 回答
0

您不必要地担心:没有“依赖地狱”,正是因为您为编译器提供了完成工作所需的所有信息。

这是我的规则:

  • 总是,总是使用头球后卫。
  • 每个 .h 文件都应该显式地#include 编译所需的所有其他 .h 文件,而不是更多的 .h 文件。

因此,如果 bh 使用来自 ah 的类型,则 bh must #include "a.h"。如果b.c使用 中的函数a.h,但b.g不使用其中的类型,那么b.c应该#include 啊

  • .h 文件中的函数不需要extern关键字,因为 IIRC 现代编译器正确地推断出这一点。
  • 使用extern全局变量很可能不受欢迎,这是有充分理由的。

  • 全局命名空间混乱。C++ 命名空间解决了这个问题,但在 C 中,您必须对所有全局类型、函数和#defines. 选择一个适合你的约定:我已经看到团队成功地为每个源文件使用了 LETTER-DIGIT-DIGIT 前缀,因此foo.h可能会变成(例如)B04_foo.h,并且所有函数/类型都获得相同的B04_前缀。这有点粗糙,但它有效。正如我所说,选择一个适合你的。

于 2013-03-25T11:13:32.870 回答