C ++中的标题保护程序

时间:2011-01-22 09:17:56

标签: c++ header guard

LearnCpp.com | 1.10 — A first look at the preprocessor。在标题保护下,有以下代码段:

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约定还是必须做的事情?

感谢。

5 个答案:

答案 0 :(得分:51)

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在文件或包含文件中没有#defined,则在#ifndef#endif指令之间编译代码”。因此,如果您在#include "add.h"文件中多次尝试.cpp,编译器将会看到ADD_H已经#defined,并且会忽略#ifndef和{{之间的代码1}}。标头保护仅阻止在同一#endif文件中多次包含头文件。标头保护不会阻止其他.cpp文件包含头文件。但是,所有.cpp个文件都可以包含受保护的头文件仅一次

答案 1 :(得分:17)

  • 预处理一个实现(“。cpp”)文件的结果是翻译单元(TU)。

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

  • 每个TU最多只能发生一次定义。 (某些定义也必须不在多个TU中;这种情况略有不同,此处不再讨论。)

  • 问题包括警卫解决在一个TU内多次包含一个给定标题时阻止多个定义错误。

  • 通过“包装”标题的内容来包含警卫工作,使第二个和后续包含为no-ops。 #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和其他地方你可以找到几种不同的防护命名样式; this answer提供了良好的标准和良好的概述。

答案 2 :(得分:3)

所有标题保护程序都只允许您的标题包含一次。 (如果它们被多次包括在内,则会被忽略。)

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

你的main应该放在.cpp文件中,但是如果你把它放在标题中,请将它放在警卫中,这样就不会多次声明。

答案 3 :(得分:1)

不,int main()进入.cpp。声明是你要放在标题中的其他东西。 _H是一种约定,你可以看到各种标题保护惯例。

答案 4 :(得分:1)

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

_H只是表明某人将使用包含警卫来包含头文件。

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