目标#ifndef FILENAME ....#endif在头文件中

时间:2010-02-04 08:17:01

标签: c++ c

我知道它可以防止多次包含头文件。但是假设我确保只在一个.cpp文件中包含此文件一次。是否仍然需要这种安全保护措施?

7 个答案:

答案 0 :(得分:12)

不,这是包含警卫的唯一目的,但使用它们应该是一个明智的选择:这样做需要的时间很少,可能会节省很多。

答案 1 :(得分:7)

您可以保证您的代码只包含一次,但是您可以保证任何人的代码都包含一次吗?

此外,想象一下:

// a.h
typedef struct { int x; int y; } type1;

// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;

// main.c
#include "a.h"
#include "b.h"

哦,不!我们的main.c仅包含一次,b.h包含a.h,因此尽管我们付出了最大的努力,我们仍然a.h次。{/ p>

现在想象这隐藏在三层或更多层的#include之后,它是一个小的仅供内部使用的标题,包含两次,这是一个问题,因为其中一个标题#undef编辑了一个宏它定义但第二个标题#define再次破坏了一些代码,需要几个小时来弄清楚为什么存在相互矛盾的定义。

答案 2 :(得分:1)

这是它唯一的存在理由。即使你认为你有这个问题,这仍然是一个好主意;它不会减慢你的代码速度或任何东西,并且永远不会伤害到额外的守卫。

答案 3 :(得分:1)

防护的目的是防止文件多次重新包含在同一个.cpp文件中。它不能防止将文件包含在多个.cpp文件中。

如果您确定头文件未包含在另一个头文件中,则不需要保护。但它仍然很好。

更好的形式是使用

#pragma once

如果您的编译器支持它。

答案 4 :(得分:1)

确保您的代码只包含一次是所谓的“标题保护”的唯一目的。

这可能很有用,就好像你的头文件之间存在循环依赖,你不会陷入包含文件的无限循环中。

答案 5 :(得分:0)

我能想到的另一个场景(我们做到了)是创建C ++模拟。

您在构建中明确定义了文件GUARD值,然后您可以通过-include my_mock.h作为附加编译器选项(我们使用g ++)添加您自己的模拟实现。

my_mock.h

#define THAT_FILE_GUARD

class ThatClass 
{
  void connect() 
  {
     std::cout << "mock connect" << std::endl;
  }
}

答案 6 :(得分:0)

使用像这样的头文件加速编译过程,想象有三个源文件使用标题(减去标题保护),这反过来意味着编译器必须包括标题(解析和lexing语法)多次过来。

使用标头防护,编译器会说'哈!我以前见过这个,并且我不会解析/ lex语法'从而加快编译过程。

希望这有帮助, 最好的祝福, 汤姆。