为什么在头文件的顶部包含指令?

qdi*_*dii 5 c c++ include

我曾经在编程类中告诉过,C++通过让程序员在函数块中的任何地方声明其变量来实现更好的可读性.这样,变量就与处理它的代码部分组合在一起.

为什么我们不为包括做同样的事情?换句话说,为什么不鼓励将include文件放在实际使用它的定义旁边?

parser::parser()
{
  // some initialization goes there which does not make use of regex
}

#include <boost/regex.hpp>
parser::start()
{
  // here we need to use boost regex to parse the document
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 8

其中一个原因#include是无上下文,它们只是纯文本包含,并且在代码中间使用它可能会产生一些不必要的影响.例如,考虑您有一个命名空间,并且此文件中的所有代码都属于命名空间:

// Include on demand:
namespace ns {
   void f() {} // does not need anything
//... lots of other lines of code
#include <vector>
   void g() { std::vector<int> v; }
}
Run Code Online (Sandbox Code Playgroud)

现在甚至可以编译好......而且错了.因为包含在命名空间内,所以文件的内容被转储到内部ns,并且包含的​​文件声明/定义::ns::std::vector.因为它只是标题,它甚至可以编译正常,只有当你尝试在具有不同子系统的接口中使用它时(在不同的命名空间中)才会失败 - 这可以修复,你只需关闭所有上下文,添加包含并重新打开相同的上下文......

在其他情况下,翻译单元中的代码可能实际上会影响包含.例如,考虑您using namespace在翻译单元中添加了一个指令.之后包含的任何标题都将具有该using namespace指令,并且可能还会产生不需要的效果.

它也可能以不同的方式更容易出错.考虑两个标头定义ffor int和的不同重载double.您可以int在文件的开头添加一个(比如版本)并使用它,然后添加另一个并使用它.现在,如果你f(5.0)在包含第二个标题的行之上调用,那么int将调用该版本 - 此时编译器只能使用过载 - 这将是一个难以捕获的错误.完全相同的代码行在文件的不同位置具有完全不同的含义(诚然已经是这种情况,但在文件的声明中,更容易找到哪个是被拾取的,为什么)

通常,包含声明将在组件中使用的元素,并将它们放在顶部,快速浏览一下依赖项列表.