如何实现标头防护,以及在它们之间可以放置什么?

发布于 2024-10-13 08:02:14 字数 697 浏览 9 评论 0原文

LearnCpp.com | 1.10 — 初步了解预处理器。在头保护下,有这些代码片段:

add.h:

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

subtract.h:

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

main.cpp:

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

在实现头保护时,提到如下:

#ifndef ADD_H
#define ADD_H

// your declarations here

#endif
  • 什么可以声明在这里吗?而且,int main() 应该在#endif 之后吗?
  • 添加 _H 是约定还是必须做的事情?

At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:

add.h:

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

subtract.h:

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

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?
  • Is adding _H a convention or a must do thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

甜柠檬 2024-10-20 08:02:15

FILENAME_H 是一种约定。如果你真的想要,你可以使用#ifndef FLUFFY_KITTENS作为标头保护(假设它没有在其他地方定义),但如果你在其他地方定义它,比如数字,那将是一个棘手的错误的小猫的某事或其他。

在头文件 add.h 中,声明实际上位于 #ifndef#endif 之间。

#ifndef ADD_H
#define ADD_H

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

#endif

最后,int main() 不应该出现在头文件中。它应该始终位于 .cpp 文件中。

澄清一下:

#ifndef ADD_H 基本上意味着“如果 ADD_H 尚未在文件或包含的文件中#define,则编译 # 之间的代码ifndef 和 #endif 指令”。因此,如果您尝试在 .cpp 文件中多次#include "add.h",编译器将看到 ADD_H 已经#define< /code> 并将忽略 #ifndef#endif 之间的代码。标头防护仅防止标头文件多次包含在同一个 .cpp 文件中。标头防护不会阻止其他 .cpp 文件包含该标头文件。但所有 .cpp 文件都可以仅包含一次受保护的头文件。

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.

In the header file add.h the declarations are literally between #ifndef and #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.

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.

时光沙漏 2024-10-20 08:02:15
  • 预处理一个实现(“.cpp”)文件的结果是一个翻译单元(TU)。

  • 标头可以包含其他标头,因此标头可以在同一 TU 内间接包含多次。 (您的 mymath.h 就是一个例子。)

  • 每个 TU 定义最多只能出现一次。 (某些定义也不得出现在多个 TU 中;这种情况略有不同,此处不予讨论。)

  • 包含防护解决的问题是在给定标头在一个 TU 中多次包含时防止出现多个定义错误。

  • 包含防护通过“包装”标头的内容来工作,这样第二个和后续包含都是无操作的。 #ifndef/#define 指令应该是文件的前两行,#endif 应该是最后一行。

  • 包含防护仅在标头中使用。不要在标头中定义主函数:将其放入实现文件中。

如果您有一个将定义类型并声明函数的标头,但还需要标头本身:

#include "other_header.h"

struct Example {};

void f();

使用包含防护“包装”它会给出文件的完整内容:

#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE

#include "other_header.h"

struct Example {};

void f();

#endif

用于包含防护的名称必须是唯一的,否则会发生冲突名称会产生令人困惑的结果。这些名称只是简单的宏,语言中没有任何内容强制执行某种风格。然而,项目惯例通常会提出要求。您可以在 SO 和其他地方找到几种不同的包含防护命名样式; 这个答案提供了很好的标准和很好的概述。

  • 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.

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 answer gives good criteria and a good overview.

无远思近则忧 2024-10-20 08:02:15

标头防护所做的只是只允许标头包含一次。 (如果多次包含它们,它们将被忽略。)

您使用的名称并不重要,但通常使用大写的文件名,包括您演示的扩展名。

您的 main 实际上应该位于 .cpp 文件中,但如果您将其放入标头中,请将其放入防护装置中,这样就不会多次声明它。

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.

浅忆 2024-10-20 08:02:15

不,int main() 位于 .cpp 中。声明是您要放入标头中的其他内容。 _H 是一种约定,您可以看到各种标头保护约定。

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.

栩栩如生 2024-10-20 08:02:15

我在头文件和定义中声明了一个声明,或者在 source.cpp 文件中声明了 int main()

_H 只是表明有人将使用包含防护来包含头文件。

如果您使用的是 MSVC++,您还可以使用 #pragma Once

I declare a declaration in header file and definitions or int main() comes in source.cpp file.

_H is there to merely indicate that someone is going to include header files using include guards.

If you're on MSVC++ you can also use #pragma once

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文