我习惯在我的物体周围放置头部防护装置,例如:
#ifndef SOMETHING_H
#define SOMETHING_H
class Something {
...
}
#endif
但是我已经得到了他们也这样做的代码:
#ifndef SOMETHING_H
#include "something.h"
#endif
对于每个包含。据说,这样更好。为什么?物体周围有防护装置,这是多余的吗?
这里对此进行了非常详细的讨论:
http://c2.com/cgi/wiki?RedundantIncludeGuards
以下是重点:
其背后的想法是,预处理器不需要打开头文件并读取内容来确定该头文件之前是否已包含,从而在编译过程中节省了一些时间。然而,现在大多数编译器已经足够聪明能够发现同一文件的多个包含并忽略后续出现的情况。
最好在头文件和类定义文件中使用这个,这样在编译时,如果在循环中引用一个文件(a.cpp引用了a.h和b.cpp,b.cpp也引用了a.h,a.h将不会被读取再次)或其他类似情况。
最让我担心的情况是你的问题是在不同的文件中定义相同的常量名称,并且可能会阻止编译器看到一些必要的常量、类、类型等。 “相信”该文件“已读”。
长话短说,将不同的 #ifndef 常量放在不同的文件中以防止混淆。
这样做的目的是为了节省编译时间。当编译看到
#include "something.h"
时,它必须出去并获取文件。如果这样做十次,最后九次基本上等于:
#if 0
...
#endif
那么您就需要付出九次查找文件并从磁盘获取文件的成本,而没有任何实际好处。 (从技术上讲,编译器可以使用技巧来尝试减少或消除这种成本,但这就是其背后的想法。)
对于小程序来说,节省的费用可能不是很大,而且这样做也没有多大好处。对于包含数千个文件的大型程序,编译花费数小时的情况并不罕见,而这个技巧可以节省大量时间。就我个人而言,在编译时间开始成为真正的问题之前我不会这样做,并且像任何优化一样,我会在进行大量更改之前仔细查看实际成本在哪里。