简体   繁体   English

C ++和C中的标题保护

[英]Header guards in C++ and C

At LearnCpp.com | LearnCpp.com | 1.10 — A first look at the preprocessor . 1.10 —首先看一下预处理器 Under Header guards , there are those code snippets: 标题保护下 ,有以下代码片段:

add.h: add.h:

#include "mymath.h"
int add(int x, int y);

subtract.h: 减去.h:

#include "mymath.h"
int subtract(int x, int y);

main.cpp: main.cpp:

#include "add.h"
#include "subtract.h"

In implementing the header guard , it is mentioned as follows: 在实现标头保护程序时 ,它提到如下:

#ifndef ADD_H
#define ADD_H

// your declarations here

#endif
  • What could the declaration be here? 声明可能在这里? And, should int main() come after #endif ? 并且, int main()应该在#endif之后吗?
  • Is adding _H a convention or a must do thing? 是将_H作为惯例还是必须做的事情?

Thanks. 谢谢。

The FILENAME_H is a convention. FILENAME_H是约定。 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. 如果确实需要,可以使用#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. 最后, int main()不应位于头文件中。 It should always be in a .cpp file. 它应始终位于.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". #ifndef ADD_H基本上意味着“如果ADD_H尚未#defined在文件中或在包含的文件,然后编译之间的代码#ifndef#endif指令”。 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 . 因此,如果您尝试在.cpp文件中多次#include "add.h" ,则编译器将看到已经#defined了ADD_H,并且将忽略#ifndef#endif之间的代码。 Header guards only prevent a header file from being included multiple times in the same .cpp file. 标头防护仅防止标头文件多次包含在同一.cpp文件中。 Header guards don't prevent other .cpp files from including the header file. 标头防护不会阻止其他.cpp文件包括标头文件。 But all .cpp files can include the guarded header file only once . 但是所有.cpp文件只能包含一次受保护的头文件。

  • The result of preprocessing one implementation (".cpp") file is a translation unit (TU). 预处理一个实现(.cpp)文件的结果是转换单元(TU)。

  • Headers can include other headers, so a header may be indirectly included multiple times within the same TU. 标头可以包含其他标头,因此标头可以间接包含在同一TU中多次。 (Your mymath.h is an example of this.) (您的mymath.h就是一个例子。)

  • Definitions can only occur at most once per TU. 每个TU定义最多只能出现一次。 (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.) (某些定义也不得位于多个TU中;这种情况略有不同,此处不再讨论。)

  • The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU. 包括后卫在内的问题解决了在一个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. #ifndef /#define指令应位于文件的前两行,而#endif则应位于文件的后两行。

  • Include guards are only used in headers. 包含保护仅在标题中使用。 Do not define your main function in a header: put it in an implementation file. 不要在头文件中定义主函数:将其放在实现文件中。

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; 在SO和其他地方可以找到几种不同的包含卫队的命名方式。 this answer gives good criteria and a good overview. 该答案给出了良好的标准和良好的概述。

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文件中,但是如果将其放在标头中,则将其放在防护中,这样就不会多次声明它了。

No, the int main() goes in a .cpp. 不,int main()以.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. _H是一个约定,您可以在其中看到各种标题保护约定。

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使用#pragma once

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM