我知道它可以防止多次包含头文件。但是假设我确保只在一个.cpp文件中包含此文件一次。是否仍然需要这种安全保护措施?
答案 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语法'从而加快编译过程。
希望这有帮助, 最好的祝福, 汤姆。