我是否应该包括每个标题,即使之前包含它?或者我可以尽可能地避免它?
例如。如果我在某个文件中使用std::string
和std::vector
。如果<string>
包括<vector>
我应该只包含<string>
或<string>
和<vector>
吗?
答案 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>
。否则,当过去包含文件的标题突然停止包含它时,您会为自己设置意外故障,因为它们不再需要它。