我曾经在编程课上被告知,C++ 通过让程序员在功能 block 的任何位置声明其变量来实现更好的可读性。这样,变量与处理它的代码部分组合在一起。
为什么我们不对包含做同样的事情? 换句话说,为什么不鼓励将包含文件放在实际使用它的定义旁边?
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
}
最佳答案
其中一个原因是 #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; }
}
现在这甚至可能编译得很好......但错误。因为包含在命名空间内,所以文件的内容被转储到 ns
内,并且包含的文件声明/定义 ::ns::std::vector
。因为它只是 header ,所以它甚至可能编译得很好,只是当您尝试在具有不同子系统(在不同命名空间中)的接口(interface)中使用它时才会失败——这可以修复,您只需要关闭所有上下文,添加包含并重新打开相同的上下文...
在其他情况下,您的翻译单元中的代码可能实际上会影响包含。例如,假设您在翻译单元中添加了一个 using namespace
指令。之后包含的任何 header 都将包含 using namespace
指令,这也可能产生不需要的效果。
它也可能以不同的方式更容易出错。考虑两个 header ,它们为 int
和 double
定义了不同的 f
重载。您可以在文件开头添加一个(比如 int
版本)并使用它,然后添加另一个并使用它。现在,如果您在包含第二个 header 的行上方调用 f(5.0)
,将调用 int
版本——此时编译器仅可使用重载—— -,这将是一个很难发现的错误。完全相同的代码行在您文件的不同位置将具有完全不同的含义(诚然,情况已经如此,但在您文件的声明中,更容易找到哪个是被选中的起来,为什么)
通常,include 声明您将在组件中使用的元素,将它们放在顶部会提供一个快速浏览的依赖项列表。
关于c++ - 为什么 include 指令在头文件之上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11696294/