C++ 和 C 中的头文件保护
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4767068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Header guards in C++ and C
提问by Simplicity
At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:
在LearnCpp.com | 1.10 - 先看看预处理器。在Header guards 下,有这些代码片段:
add.h:
添加.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
减去.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp:
主.cpp:
#include "add.h"
#include "subtract.h"
In implementing the header guard, it is mentioned as follows:
在实现header guard 时,提到如下:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
- What could the declaration be here? And, should
int main()
come after#endif
? - Is adding
_H
a convention or a must do thing?
- 这里的声明可能是什么?而且,应该
int main()
在后面#endif
吗? - 添加
_H
约定还是必须做的事情?
Thanks.
谢谢。
回答by The Communist Duck
The FILENAME_H
is a convention. If you really wanted, you could use #ifndef FLUFFY_KITTENS
as a header guard (provided it was not defined anywhere else), but that would be a tricky bug if you defined it somewhere else, say as the number of kittens for something or other.
这FILENAME_H
是一个约定。如果你真的想要,你可以#ifndef FLUFFY_KITTENS
用作头部保护(假设它没有在其他任何地方定义),但如果你在其他地方定义它,这将是一个棘手的错误,比如某物的小猫数量。
In the header file add.h the declarations are literally between #ifndef
and #endif
.
在头文件 add.h 中,声明字面上位于#ifndef
和之间#endif
。
#ifndef ADD_H
#define ADD_H
#include "mymath.h"
int add(int x, int y);
#endif
Finally, int main()
shouldn't be in a header file. It should always be in a .cpp
file.
最后,int main()
不应在头文件中。它应该总是在一个.cpp
文件中。
To clear it up:
要清除它:
#ifndef ADD_H
basically means "if ADD_H has not been #defined
in the file or in an included file, then compile the code between #ifndef
and #endif
directives". So if you try to #include "add.h"
more than once in a .cpp
file, the compiler will see what the ADD_H was already #defined
and will ignore the code between #ifndef
and #endif
. Header guards only prevent a header file from being included multiple times in the same .cpp
file. Header guards don't prevent other .cpp
files from including the header file. But all .cpp
files can include the guarded header file only once.
#ifndef ADD_H
基本上意味着“如果 ADD_H 没有出现#defined
在文件或包含的文件中,那么编译#ifndef
和#endif
指令之间的代码”。所以,如果你尝试#include "add.h"
不止一次在一个.cpp
文件中,编译器会看到什么ADD_H已经#defined
和将忽略之间的代码#ifndef
和#endif
。头保护只是防止一个头文件被多次包含在同一个.cpp
文件中。头文件保护不会阻止其他.cpp
文件包含头文件。但是所有.cpp
文件只能包含一次受保护的头文件。
回答by Fred Nurk
The result of preprocessing one implementation (".cpp") file is a translation unit (TU).
Headers can include other headers, so a header may be indirectly included multiple times within the same TU. (Your mymath.h is an example of this.)
Definitions can only occur at most once per TU. (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.)
The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU.
Include guards work by "wrapping" the contents of the header in such a way that the second and subsequent includes are no-ops. The #ifndef/#define directives should be the first two lines of the file, and #endif should be the last.
Include guards are only used in headers. Do not define your main function in a header: put it in an implementation file.
预处理一个实现(“.cpp”)文件的结果是一个翻译单元(TU)。
标头可以包含其他标头,因此一个标头可以在同一个 TU 内多次间接包含。(你的 mymath.h 就是一个例子。)
每个 TU 最多只能出现一次定义。(一些定义也不能在多个 TU 中;这种情况略有不同,这里不讨论。)
当给定的标头在一个 TU 中多次包含时,包含保护解决的问题是防止出现多个定义错误。
包含守卫通过“包装”标题的内容来工作,使得第二个和后续包含是无操作的。#ifndef/#define 指令应该是文件的前两行,#endif 应该是最后一行。
包含保护仅用于标题中。不要在头文件中定义你的主函数:把它放在一个实现文件中。
If you have a header that will define a type and declare a function, but also needs a header itself:
如果您有一个将定义类型并声明一个函数的标头,但也需要一个标头本身:
#include "other_header.h"
struct Example {};
void f();
"Wrapping" it with include guards gives the complete contents of the file:
用包含守卫“包装”它给出了文件的完整内容:
#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE
#include "other_header.h"
struct Example {};
void f();
#endif
The name used for the include guard must be unique, otherwise conflicting names will give confusing results. These names are only simple macros, and there is nothing in the language which enforces a certain style. However, project conventions usually impose requirements. There are several different include guard naming styles you can find here on SO and elsewhere; this answergives good criteria and a good overview.
用于包含保护的名称必须是唯一的,否则名称冲突会产生混淆结果。这些名称只是简单的宏,在语言中没有强制某种风格的东西。但是,项目约定通常会提出要求。您可以在 SO 和其他地方找到几种不同的 include 保护命名样式;这个答案给出了很好的标准和很好的概述。
回答by user541686
All the header guards do is to only allow your headers to be included once. (If they're included multiple times, they're ignored.)
所有标题守卫所做的就是只允许您的标题被包含一次。(如果它们被多次包含,它们将被忽略。)
The name you use doesn't matter, but it's conventional to use the file name in caps, including the extension like you demonstrated.
您使用的名称无关紧要,但通常使用大写的文件名,包括您演示的扩展名。
Your main
should really be in a .cpp
file, but if you're putting it in a header, put it inside the guards so it isn't declared multiple times.
你main
真的应该在一个.cpp
文件中,但如果你把它放在一个标题中,把它放在警卫里,这样它就不会被多次声明。
回答by Puppy
No, the int main() goes in a .cpp. The declarations are the other stuff you were gonna put in the header. _H
is a convention, you can see various header guard conventions around.
不,int main() 放在 .cpp 中。声明是您要放在标题中的其他内容。_H
是一个约定,您可以在周围看到各种标题保护约定。
回答by cpx
I declare a declaration in header file and definitions or int main()
comes in source.cpp
file.
我在头文件和定义中声明了一个声明或int main()
进入source.cpp
文件。
_H
is there to merely indicate that someone is going to include header files using include guards.
_H
是否仅表明有人将使用包含防护包含头文件。
If you're on MSVC++ you can also use #pragma once
如果您使用的是 MSVC++,您还可以使用#pragma once