好的,可能这个问题已经有了答案,但我不知道要搜索哪个关键字(我的搜索结果大部分仅包括.h
中的警卫,而不是.cpp
)
有时我在cpp
中看到每个#include
行都有一个额外的包含守卫(有时甚至包含.h
已经拥有自己的包含守卫),如下所示:
SomeClass.cpp
#ifndef__A__
#include A.h
#endif
#ifndef__B__
#include B.h
#endif
#ifndef__C__
#include C.h
#endif
而不是
SomeClass.cpp
#include A.h
#include B.h
#include C.h
,这包括后卫的功能是什么?
答案 0 :(得分:2)
John Lakos在他的书Large-Scale C++ Software Design中推荐了在.cpp文件中使用包含警卫的做法。我不知道他之前是否有人推荐过这种做法。
说你有
A.H:
#ifndef __A__
#define __A__
#include "B.h"
#include "C.h"
// ...
// ...
// ...
#endif
B.h:
#ifndef __B__
#define __B__
// ...
// ...
// ...
#endif
C.h:
#ifndef __C__
#define __C__
// ...
// ...
// ...
#endif
SomeClass.cpp:
#ifndef __A__
#include "A.h"
#endif
#ifndef __B__
#include "B.h"
#endif
#ifndef __C__
#include "C.h"
#endif
编译SomeClass.cpp时,包含A.h的内容。作为包含A.h内容的副产品,还包括B.h和C.h的内容。此外,还定义了预处理器宏__A__
,__B__
和__C__
。当行
#ifndef __B__
处理,因为已经定义了__B__
,所以跳过下一行。
如果SomeClass.cpp只有:
#include "A.h"
#include "B.h"
#include "C.h"
必须打开并处理文件B.h.由于包含防护,文件的内容不会再包含在内,但必须打开和关闭文件。
通过使用第一个策略,您可以避免打开和关闭B.h和C.h.对于大型C ++项目,John Lakos断言,成本太高了。因此,即使在.cpp文件中,使用包含保护的建议。
答案 1 :(得分:1)
这意味着如果文件已经包含(symbol_specific_to_header
已定义),甚至不检查头文件的内容。
在古代打开文件并且检查内容是否已经包含在标题本身是昂贵的(打开,阅读和关闭标题的成本非常高)这个技巧被用来减少编译时间。
但是在现代系统上,不需要这个技巧。虽然这不会造成任何伤害,除了代码重复并添加混乱,这将起作用。建议在包含文件中添加hashguards。
这是头文件的外观和包含方式。
新风格:
/* A.h */
#pragma once
...
或
/* A.h */
#ifndef A_H
#define A_H
...
#endif
用法:
#include "A.h"
或者使用预编译的标头。
旧式
你提到的古老风格:
/* A.h */
#define A_H
...
用法:
#ifndef A_H
#include "A.h"
#endif
答案 2 :(得分:0)
这是为了防止包含相同的标题两次。
A.h可能看起来像这样
#define __A__
#include B.h
没有守卫,B.h将被包括两次,这可能会导致错误。因此,cpp中的#ifndef行只是保护自己免受包括其他标题在内的标题的攻击。</ p>