我应该包括每个标题吗?

时间:2014-10-28 14:55:57

标签: c++ c++11

我是否应该包括每个标题,即使之前包含它?或者我可以尽可能地避免它? 例如。如果我在某个文件中使用std::stringstd::vector。如果<string>包括<vector>我应该只包含<string><string><vector>吗?

2 个答案:

答案 0 :(得分:29)

如果在文件中使用标题相关实体(例如某种类型),则应包含相关标题。不要依赖标题来互相包含。 如果您使用它,请加入

C ++标准库不要求在<string>中包含<vector>,反之亦然。尝试使用这样的功能会将代码限制为特定的实现。通常,标准库标头可能包含或不包含其他标头(或其自己的内部标头),但未指定顺序或方式。一个值得注意的例外是<initializer_list>,它必须包含在few of the other standard headers中。 也可能发生对此未指定顺序或方式的更改,从而破坏以前使用更新的编译器或更新的标准库实现编译代码(已知会发生这种情况)

还要考虑如果头文件是类的定义,那么它应该包括该类定义所需的内容。关联的.cpp应包含其关联的.h以及实现该类所需的其余文件。 不需要它,不包含它;不要包含超过需要的内容(llvm style guide)。这里有一个例外是templates (that don't have an associated .cpp);此异常将适用于其他仅标头实现。

值得注意的是,维护包括您使用的 从长远来看可能很困难;因此有意义的是,在编码周期的开始,包括接口所需的内容是很重要的;然后再次检查包含对代码进行的任何合理更改。

似乎有一些进展w.r.t.这方面的工具,例如iwyu project,使用clang工具链,似乎也支持msvc。

一个反例如果标题的原因是包含其他标题,那么也许,但即便如此,我会非常小心 - 确保明确定义它包含的内容。一个例子可以是预编译头。

答案 1 :(得分:8)

通常,您应该将标头依赖关系视为实现的一部分,而不是作为接口的一部分。

您不应该依赖包含其他标头的标头。如果您的班级需要使用std::vector,请加入<vector>;如果您需要std::string,请添加<string>。否则,当过去包含文件的标题突然停止包含它时,您会为自己设置意外故障,因为它们不再需要它。