C++ 在c+中包含两次头文件+;
如果我在文件中两次包含C++ 在c+中包含两次头文件+;,c++,header-files,C++,Header Files,如果我在文件中两次包含iostream或任何其他头文件,会发生什么情况? 我知道编译器不会抛出错误 代码会被添加两次还是会在内部发生什么 当我们包含头文件时,实际会发生什么情况?防止编译器实际看到文件内容两次 Include guard基本上是头文件开头和结尾的一组预处理器条件指令: #ifndef SOME_STRING_H #define SOME_STRING_H //... #endif 现在,如果您包含文件两次,则不会定义第一次循环宏的某些字符串,因此编译器会处理和查看文件的内
iostream
或任何其他头文件,会发生什么情况?
我知道编译器不会抛出错误
代码会被添加两次还是会在内部发生什么
当我们包含头文件时,实际会发生什么情况?防止编译器实际看到文件内容两次
Include guard基本上是头文件开头和结尾的一组预处理器条件指令:
#ifndef SOME_STRING_H
#define SOME_STRING_H
//...
#endif
现在,如果您包含文件两次,则不会定义第一次循环宏的某些字符串,因此编译器会处理和查看文件的内容。但是,由于#ifdef
之后的第一件事是#define
,定义了一些字符串
,编译器看不到头文件的下一次内容
为避免冲突,include guard中使用的宏的名称取决于头文件的名称。由于预处理器代码如下所示,它只是被跳过:
#ifndef MY_HEADER_H
#define MY_HEADER_H
<actual header code here>
#endif
\ifndef MY\u HEADER\u H
#定义我的标题
#恩迪夫
因此,如果包含两次,则已定义了MY_HEADER\u H
,预处理器将跳过#ifndef
和#endif
之间的所有内容。头文件很简单。当您#include
时,所发生的一切就是标题的内容基本上被粘贴到文件中。为了防止多次包含头文件,使用了包含保护
,这就是为什么在大多数头文件中,您会看到类似于
#ifndef SOME_HEADER_FILE_GUARD
#define SOME_HEADER_FILE_GUARD
//Contents of Header
#endif
视情况而定。除了
,本标准要求
第二个(以及更高版本)包括一个标准标题,该标题为no-op
然而,标题的特征;编译器将(至少)
(概念上)每次阅读并包含所有标题文本
遇到的问题包括
在这种情况下避免多重定义的标准做法是
使用包含保护:头中的所有C++代码将是
用类似于:
#ifndef SPECIAL_NAME
#define SPECIAL_NAME
// All of the C++ code here
#endif SPECIAL_NAME
显然,每个头都需要不同的名称。在应用程序中,
通常可以根据文件名和文件名建立约定
位置;类似于子系统的文件名
,带有
C++符号中的字符不合法(如果您在其中使用它们)
文件名)映射(通常所有内容都是大写的)。对于
在图书馆中,最好的做法是生成一个合理的长
字符的随机序列;更频繁(尽管肯定
(从实施质量的角度来看)是为了确保
每一个这样的符号都以一个记录在案的前缀开头
当然,系统库可以使用保留符号(例如符号
以下划线开头,后跟大写字母)到
保证没有冲突。或者它可以完全使用一些
不同的、依赖于实现的技术。比如微软,,
使用编译器扩展名#pragma一次
;g++使用包括
始终以\u GLIBCXX
开头(这在用户代码中不是合法符号)。
这些选项不一定对您可用。包含头文件时,其所有内容都会复制到“#include”指令所在的行。这是由预处理器完成的,是编译过程中的一个步骤
对于标准文件(如iostream或存储在本地目录中的用户自制的“.h”文件),此过程是相同的。但是,语法略有不同
我们使用#include
来处理存储在库中的像“iostream”这样的文件。然而,对于本地目录中的头文件,我们使用#include“filename.h”
现在,如果我们包含两次头文件怎么办:
理想情况下,内容应该复制两次。但是
许多头文件使用现代做法,即一次提及#pragma
,这指示预处理器仅复制一次内容,而不管头文件包含多少次
一些非常古老的代码使用了一个称为“include gaurds”的概念。我不会解释它,因为其他答案做得很好
使用pragma once
是一种简单而现代的方法,但是,以前使用过很多include-guard,这是一个相对复杂的解决方案。很大的帮助::请注意:在使用Microsoft工具时,您经常会看到#pragma once
,它具有与#ifndef…
相同的功能。为了更好地兼容编译器,您应该使用后者。还要注意的是,大多数编译器都会识别此模式,甚至在第二次看到文件时都不会打开它。这实际上并不能回答问题。我对原来的问题感兴趣,因为我在看别人的代码。