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