C ++头文件没有包含任何其他头文件的任何充分理由?

时间:2011-08-03 23:23:58

标签: c++ coding-style header-files

我看过一个标题包含这样的样式,其中头文件不包含其他头文件,相应的* .cpp文件必须包含所有依赖项(并按正确的顺序包含它们)。在过去的好日子里,这可能会使构建依赖性跟踪变得更容易(但我只是在猜测)。现在有充好的理由吗?

档案“B.h”:

#ifndef _B_h_
#define _B_h_

// Note we do not #include "A.h" that contains class A declaration.

class B
{
public:
   A a; // An A object.
};
#endif // _B_h_

档案“B.cpp”:

#include "A.h" // Must include this before B.h, otherwise class A not defined in B.h
#include "B.h"

...

6 个答案:

答案 0 :(得分:8)

是的,那将是不好的做法,因为如果某人得到错误的订单,他们会得到他们可能或可能无法弄清楚的错误。如果所有头文件都包含防护,那么包含所需的所有其他头的一个头将不会成为问题,这应该是它应该是什么。

答案 1 :(得分:5)

似乎无论谁编写该代码都误解了减少包含标头数量的共同建议。通常建议删除不必要的 #include <>指令,以期加速编译。实际上,在大型项目中,它可能会通过以下方式显着加速编译:

  1. 减少编译器需要打开以编译任何给定源文件的头文件数;
  2. 减少标题更改后需要重新编译的源文件数。
  3. 一般来说,除非相关标题中定义的类是:

    ,否则人们会建议(使用我所参与的所有项目的编码标准)使用类的前向声明。
    1. 用作基类;
    2. 用作数据成员;
    3. 有一个不完整的官方规范(例如,标准库容器只要有默认值就允许有额外的模板参数,因此转发声明它们是非标准的。)
    4. 在案例1和案例2中,#include <>指令必须出现在所有依赖源文件和标头中的类定义之前。基本上,它只是将#include <>指令从头部移动到每个依赖项中。它导致更多的代码并且没有任何好处(例如编译时间等将是相同的)。出于这个原因,此建议还附带编码标准中的另一个条目:每个头文件应编译“独立”(例如,包含在源文件的第一行)。

答案 2 :(得分:4)

这是一个非常糟糕的做法。让编译器找出正确的顺序 - 它不易出错。标题应该编译为好像它们是自己包含的 - 即,如果你的TU只包含#include "B.h"

答案 3 :(得分:2)

  

现在有充分的理由吗?

不,不是真的。人们做各种“会工作”的东西要么是因为他们不知道更好,不关心或者有更重要的事情需要担心。当您的语言依赖于预处理器而不是真正的模块导入系统时,就会发生这种情况。

我想说最好的做法是确保#including你的东西的人永远不必担心包含或隐藏的先决条件的顺序。当然,除非你的手被第三方的愚蠢宏观技巧所迫,否则无论如何。

答案 4 :(得分:2)

是的,我建议#including'任何标题中任何INTERFACE的依赖。

在这种情况下,是的:我会#include“A”(因为B的界面取决于A)。

否则,如果实现使用“A”(但标题没有),我只会在.cpp中#include A(因为它不是界面的一部分)。

在任何情况下我都不希望标题的顺序重要,如果可以的话。通常,标题顺序应该不重要。

... IMHO

PS: 就像Bjarne Stroustrup所希望的那样,预处理器和预处理器宏仍然非常适合我们。当然在C-land中,当然在几乎任何Microsoft API中。尊重这一事实是一种很好的形式。

答案 5 :(得分:2)

我会考虑这种糟糕的风格。这将导致很难理解错误。

您可能会这样做的原因是每次更改单个头文件时都要避免重新编译大量代码。如果你发现自己处于这种情况,你可能会遇到设计问题。