用C ++标题保护

在LearnCpp.com | 1.10 – 先看预处理器 。 在Header卫士下 ,有这些代码片段:

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是一个惯例还是一个必须做的事情?

谢谢。

FILENAME_H是一个惯例。 如果你真的想要的话,你可以使用#ifndef FLUFFY_KITTENS作为头文件(如果没有在其他地方定义的话),但是如果你把它定义在其他地方,比如某些东西的小猫的数量,那将是一个棘手的错误。

这些声明实际上是下面的代码。

 #ifndef ADD_H #define ADD_H #include "mymath.h" int add(int x, int y); #endif 

最后, int main()不应该在头文件中。 它应该总是在.cpp文件中。

要清除它:

#ifndef基本上是指“如果这个文件还没有被查看,看看它”。 如果已经查看过,则会跳过文件中的所有内容。 所以如果你包含了两次,那么当第一次包含它的时候,编译器会看到add函数是什么。 它也将尝试包括尚未被查看过的mymath.h文件。

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

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

  • 定义每TU最多只能发生一次。 (有些定义也不能在多个TU中;这种情况稍有不同,这里不讨论)。

  • 当一个TU中包含一个给定的头部不止一次时,包括警卫解决的问题防止了多重定义错误。

  • 包括警卫通过“包装”标题内容的方式工作,使得第二个和后续的包含没有操作。 #ifndef /#define指令应该是文件的前两行,而#endif应该是最后一行。

  • 包括守卫只用于标题。 不要在头文件中定义你的主函数:把它放在一个实现文件中。

如果你有一个头文件来定义一个types并声明一个函数,但是也需要一个头文件本身:

 #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 

用于包含守卫的名称必须是唯一的,否则相互冲突的名称会导致混淆。 这些名称只是简单的macros,并没有什么强制执行某种风格的语言。 但是,项目惯例通常会提出要求。 在SO和其他地方可以find几种不同的警卫命名风格, 这个答案给出了很好的标准和一个好的概述。

所有的标头守卫是只允许你的头被包含一次。 (如果多次包含它们,则会被忽略。)

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

你的main应该在.cpp文件中,但是如果你把它放在一个头文件中,把它放在守卫中,这样就不会多次声明。

不,int main()进入.cpp。 声明是你要在标题中的其他东西。 _H是一个惯例,你可以看到各种各样的头球守卫惯例。

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

_H在那里只是表示有人打算使用include guard来包含头文件。

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