2011-01-22 86 views
25

At LearnCpp.com | 1.10 — A first look at the preprocessor。下部首警卫,还有那些代码片断:C++中的标题警卫

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

谢谢。

+0

那么,上面实现的头部gurad是否插入了“add.h”? – Simplicity 2011-01-22 09:47:54

回答

1

不,int main()进入.cpp。声明是你要放在标题中的其他内容。 _H是一个约定,你可以看到各种各样的标题守卫约定。

3

所有标头守卫都只允许您的标题包含一次。 (如果它们被多次包含,它们将被忽略。)

您使用的名称无关紧要,但是在大写字母中使用文件名是常规操作,包括像您演示的扩展名。

您的main应该确实在.cpp文件中,但是如果您将它放在标题中,请将它放在警卫内部,以免它多次声明。

+0

感谢您的回复。但是,对于“mymath.h”,这里不是问题,并且在“main.cpp”中包含它两次,因为我们有两个包含“add.h”和“subtract.h”的内容? – Simplicity 2011-01-22 09:50:14

+0

是的,的确如此。这就是为什么你应该在那里放置一个`MATH_H`后卫。 (我不确定我是否正确理解你的问题......) – Mehrdad 2011-01-22 09:56:33

+0

你在哪里指“在那里”?你的意思是mymath.h吗? – Simplicity 2011-01-22 17:09:28

46

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

1

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

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

如果你在MSVC++,你也可以使用#pragma once

17
  • 预处理一个执行的结果( “的.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和其他地方可以找到几种不同的警卫命名风格, this answer提供了很好的标准和良好的概述。