C ++标题保护对象和用法?

时间:2013-11-06 00:01:51

标签: c++ include-guards

我习惯在我的对象周围放置标题守卫,如:

#ifndef SOMETHING_H
#define SOMETHING_H

class Something {
...
}
#endif

但我也得到了代码:

#ifndef SOMETHING_H
#include "something.h"
#endif
每个包含

。据说,这更好。为什么?围绕物体的守卫是多余的吗?

4 个答案:

答案 0 :(得分:5)

它背后的想法是预处理器不需要打开头文件并读取内容以确定先前已包含该头,从而在编译期间节省了一些时间。但是,现在大多数编译器已经smart enough发现同一文件的多个包含,并忽略后续出现。

答案 1 :(得分:5)

这里有非常详细的讨论:
http://c2.com/cgi/wiki?RedundantIncludeGuards

以下是重点:

  • 是的,这是多余的,但对于某些编译器来说,它可能会更快,因为如果不需要,编译器将避免打开头文件。
  • “好的编译器不需要这个习惯用法。他们注意到标题是使用include-guard惯用语(即文件中的所有非注释代码都用#ifndef括起来。)它们存储了一个内部表头文件和保护宏。在打开任何文件之前,他们检查保护的当前值,然后跳过整个文件。“
  • “冗余防护有几个缺点。它们使得包含部分更难以阅读。它们是多余的。它们泄漏了防护名称,这应该是标题的秘密实现细节。例如,如果有人重命名警卫他们可能会忘记更新所有保护名称的地方。最后,如果有人在守卫之外添加代码,他们就会出错。当然,他们只是一个编译时效率黑客。只有当其他所有时候使用失败“。

答案 2 :(得分:0)

在头文件和类定义文件上有这个好,所以在编译时,如果一个文件被循环引用(a.cpp引用啊和b.cpp,而b.cpp也引用啊,啊不会再读一遍)或其他类似的案例。

最让我担心的问题是,在不同的文件中定义了相同的常量名称,并且可能阻止编译器看到一些必要的常量,类,类型等等。它会“相信”该文件已“已读”。

长话短说,将不同的#ifndef常量放在不同的文件中以防止混淆。

答案 3 :(得分:0)

这样做的目的是节省编译时间。当编译看到#include "something.h"时,它必须出去并获取文件。如果这样做十次而后九次基本上都是:

#if 0
...
#endif
然后,您需要支付查找文件并从磁盘中取出文件9次的成本,这没有任何实际好处。 (从技术上讲,编译器可以通过技巧来尝试减少或消除这种成本,但这背后的理念就是这样。)

对于小型程序,保存可能不是很重要,并且这样做没有多大好处。对于由数千个文件组成的大型程序,编译花费数小时并不罕见,这个技巧可以节省大量时间。就个人而言,在编译时间开始成为一个真正的问题之前,我不会做的事情,就像任何优化一样,我会仔细研究实际成本在哪里进行一系列更改。