7

当我创建一个将由多个开发人员使用的头文件时,是否认为是一种良好的编程习惯,使该头文件在其中使用的所有定义和声明方面自给自足。

例如:

头文件 1:types.h

#ifndef TYPES_H
#define TYPES_H
typedef unsigned int uint16
#endif

头文件2:myheader.h

#ifndef MYHEADER_H
#define MYHEADER_H
uint16 myfunc(void);
#endif

我在 myheader.h 中使用了 uint16 ,但不包括 types.h 。因此,如果有人想在他们的源文件中包含 myheader.h,他们应该首先包含“types.h”,然后包含“myheader.h”。所以这实际上是在迫使开发人员以特定的顺序包含头文件。我一直认为这是不好的做法,但今天我在公司遇到了一些代码,在其中获取在一个文件中声明的函数,您需要包含至少 4 个其他头文件。所以现在我很困惑,我是否遗漏了什么,是否有任何地方可以将其视为预期行为。

4

6 回答 6

5

用不必要的类型污染全局命名空间是不好的做法。您能做的最好的事情是尽可能提供前向声明,并include在必要时提供其他文件。uint16在您的简化情况下,您应该包含在使用它的每个标头中定义的标头。

例如,如果您可以前向声明类型,则这是首选。基本原理是,如果您实际上不使用该类型,则前向声明就足够了。如果您确实使用了该类型,则应该在显式声明它的地方包含标头。

于 2012-08-07T18:06:55.853 回答
4

你最好只创建一些包含守卫,然后#include "types.h"进入 myheader.h。不要让别人思考(至少不是这样)。

于 2012-08-07T18:06:47.773 回答
3

具体回答您的问题:是的,头文件应该是自给自足的。它应该包括允许它编译所需的每个头文件。

通常,大多数现代库都有适当的保护措施,以便编译器只能“看到”一次头文件。先到先得。所以不要太在意这一点(尽管验证它永远不会有坏处)。

于 2012-08-07T18:11:28.487 回答
1

公共标头应提供使用其公开的接口所需的所有定义,仅此而已。

于 2012-08-07T18:31:58.937 回答
0

这可能是一个惯例问题,但在几乎所有类似的情况下, myheader.h#includetypes.h一开始就包含。

于 2012-08-07T18:08:21.750 回答
0

所有标头都应该是自给自足的,除非用#error 明确说明,除非定义了某些定义。

我总是将 CPP 文件的匹配标头作为第一个包含,以确保它们始终是可编译的。

于 2012-08-07T20:56:30.370 回答