C++ include guard in.cpp(而不是in.h)的功能是什么?

C++ include guard in.cpp(而不是in.h)的功能是什么?,c++,C++,好的,可能这个问题已经有答案了,但我不知道要搜索什么关键字(我的大多数搜索结果都是关于include guard in.h,而不是.cpp) 有时我看到在cpp中,每个#include行都有一个额外的include防护(有时甚至include.h也有自己的include防护),如下所示: SomeClass.cpp #ifndef__A__ #include A.h #endif #ifndef__B__ #include B.h #endif #ifndef__C__ #include C.h

好的,可能这个问题已经有答案了,但我不知道要搜索什么关键字(我的大多数搜索结果都是关于include guard in
.h
,而不是
.cpp

有时我看到在
cpp
中,每个#
include
行都有一个额外的include防护(有时甚至include
.h
也有自己的include防护),如下所示: SomeClass.cpp

#ifndef__A__
#include A.h
#endif
#ifndef__B__
#include B.h
#endif
#ifndef__C__
#include C.h
#endif
#include A.h
#include B.h
#include C.h
而不是

SomeClass.cpp

#ifndef__A__
#include A.h
#endif
#ifndef__B__
#include B.h
#endif
#ifndef__C__
#include C.h
#endif
#include A.h
#include B.h
#include C.h

,此include guard的功能是什么?

它用于防止两次包含同一个标头

A.h可能看起来像这样

#define __A__
#include B.h

如果没有防护装置,B.h将包含两次,这可能会导致错误。因此,cpp中的#ifndef行只是保护自己不受包括其他头文件在内的头文件的影响。

这意味着,如果头文件已经包含,甚至不检查头文件的内容(
定义了特定于符号的头文件

在古代,当打开一个文件并检查内容是否已经包含在头文件中时,成本很高(打开、读取和关闭头文件的成本非常高),这一技巧被用来减少编译时间

但在现代系统中,这种技巧是不需要的。虽然这不会造成任何伤害,但代码会重复并增加混乱,这是可行的。尽管建议在include文件中添加hashguard

这就是头文件的外观和包含方式

新样式:

/* A.h */
#pragma once
...

用法:

#include "A.h"
#ifndef A_H
#include "A.h"
#endif
或使用预编译头

旧式

您提到的古代风格:

/* A.h */
#define A_H
...
用法:

#include "A.h"
#ifndef A_H
#include "A.h"
#endif

John Lakos在他的书中推荐了在.cpp文件中使用include-guard的做法。我不知道在他之前是否有人推荐过这种做法

说你有

A.h:

B.h:

C.h:

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的含量也包括在内。此外,还定义了预处理器宏
\uuuuu A\uuuuu
\uuuu B\uuuu
\uu C\uuu
。排队的时候

#ifndef __B__
已处理,因为已定义了
\uuuu B\uuu
,因此跳过下一行

如果SomeClass.cpp刚刚:

#include "A.h"
#include "B.h"
#include "C.h"
必须打开并处理文件B.h。由于包含保护,文件内容将不再包含,但必须打开和关闭文件


使用第一策略,避免了对大型C++项目的开封和关闭B.H和C.H的成本,John Lakos断言,成本太高。因此,即使在.CPP文件中也使用了包含保护的建议。

它们被称为外部包含保护,通常被大型C++软件设计书所流行。是的,这是打开文件的费用。但是有B.h和C.h似乎根本没有必要吗?我知道他们应该是谁removed@tejashs对不起,我不能理解你的担心。你能详细说明一下吗
b.h
c.h
是独立的文件,就像
a.h
一样,可能是完全正交的。如果我们知道b.h和c.h包含在a.h中,我们根本不需要将它们包含在cpp文件中。只有a.h.应该suffice@tejashs您如何知道
a.h
中包含
b.h
c.h
?我可能错过了。它是在某个地方写的还是暗示的?我又读了一遍这个问题,但运气不好。请注意,一些现代编译器(如GCC)还记得头保护,这使得这项技术变得多余。