在头文件中包含指令?

时间:2012-09-23 18:29:58

标签: c++ include c-preprocessor

  

可能重复:
  where should “include” be put in C++

显然,对于是否将#include指令放入C ++头文件(或者作为替代方法,只将#include放入cpp文件),有两种“思想流派”。有人说没关系,有人说这只会导致问题。有人知道这个讨论是否已经得出结论是什么?

5 个答案:

答案 0 :(得分:6)

我不知道有任何关于此问题的学校。当需要它们时将它们放在标题中,否则转发声明并将它们放入需要它们的.cpp文件中。将标题包含在不需要的地方没有任何好处。

答案 1 :(得分:3)

我发现有效的是遵循一些简单的规则:

  • 标题应是自给自足的,即他们应声明他们需要的类别,并包括他们使用的任何定义的标题。
  • 标题应该尽可能地减少依赖关系而不违反前一点。

获得第一个点是相当容易的:从实现它声明的内容的源代码中首先包含头文件。然而,第二点完全正确并非易事,我认为需要工具支持才能使其完全正确。但是,一些不必要的依赖通常并没有那么糟糕。

答案 2 :(得分:2)

根据经验,只要在那里需要完整定义标题,就不要在标题中包含标题。大多数时候你在头文件中使用类的指针,所以在那里转发声明就好了。

答案 3 :(得分:1)

这些不是宗教的思想流派。实际上,这两种方法都有其优点和缺点,并且任何一种方法都需要遵循某些实践才能获得成功。但是这些方法中只有一种会“扩展”到大型项目中。

不在头文件中包含标题的优点是编译速度更快。但是,这个优势并不是来自头文件只读一次,因为即使你在头文件中包含头文件,智能编译器也可以解决这个问题。速度优势来自于您只包含那些对给定源文件严格必需的标头。另一个优点是,如果我们查看源文件,我们可以确切地看到它的依赖关系:头文件的平面列表清楚地向我们提供。

但是,这种做法很难维护,特别是在有很多程序员的大型项目中。如果您想使用模块foo,这会非常不方便,但您不能只#include "foo.h":您需要包含35个其他标题。

最终发生的事情是:程序员不会浪费时间发现他们只需要添加模块foo所需的精确最小标头集。为了节省时间,他们将转到一些类似于他们正在处理的示例源文件,并剪切并粘贴所有#include指令。然后他们会尝试编译它,如果它没有构建,那么他们将剪切并粘贴来自其他地方的更多#include指令,并重复它直到它工作。

最终结果是,您一点一点地失去了编译速度更快的优势,因为您的文件现在包含了不必要的标头。而且,#include指令列表不再显示真正的依赖关系。此外,当你现在进行增量编译时,由于这些错误的依赖性,你编译的数量超过了必要的数量。

每个源文件几乎包含每个标头后,您可能还有一个包含所有标头的大everything.h,然后在每个源文件中都有#include "everything.h"

所以这种只包含特定标题的做法最好留给那些由少数开发人员精心维护的小项目,这些开发人员有足够的时间来维护最小的伦理,包括手工依赖,或编写工具来追捕不必要的{ {1}}指令。

答案 4 :(得分:1)

我认为这个问题很久以前就解决了:标题应该是自包含的(不应该依赖于用户之前包含其他标题 - 这个方面已经解决了很长时间以至于某些问题不均衡我知道有一个关于这个问题的辩论,但是你的 put仅包含在.cpp 中似乎暗示了这一点)但是最小(即当声明足以自我控制时,不应包括定义)。 / p>

自我遏制的原因是维护:如果要修改标题并且现在依赖于新的内容,则必须跟踪它用于包含新依赖项的所有位置。顺便说一句,确保自我控制的标准技巧是包括头文件,该头文件首先在.cpp中为.cpp中定义的内容提供声明。

相关问题