与包含头文件混淆

Confusion with including header files

本文关键字:文件 包含头      更新时间:2023-10-16

当我包含一个头文件时,比如,

//myheader.h
#ifndef MY_HEADER_H
#define MY_HEADER_H
//....
#endif

,

//mycpp1.cpp
#include "myheader.h"

我被告知的是,当mycpp1.cpp包含myheader.h时,MY_HEADER_H被定义,因此任何再次包含它的尝试都将导致false。

现在,如果我想把它包含在mycpp2.cpp.

//mpcpp2.cpp
#include "myheader.h"

是否会被包含,还是使用与第一次包含时相同的声明?

每个文件的预处理器定义是单独的。因此,如果您将myheader.h #include放入两个独立的.cpp文件中,它将被包含两次,而不是一次。

预处理器定义是当前编译单元的本地定义。

当然也有复杂的情况,但重点是:

尝试将.cpp(源)文件视为不同的实体。如果你不做奇怪的事,那么如果你删除了所有的。cpp文件,除了你讨厌的那个,仍然可以编译,因为在编译阶段不需要对于定义,您只关心事物的名称(声明)。

因此,一次编译N个源文件实际上是这样的:

[ *.H + SOURCE1.CPP ] --> SOURCE1.O
[ *.H + SOURCE2.CPP ] --> SOURCE2.O
...
[ *.H + SOURCEN.CPP ] --> SOURCEN.O

,其中每行都是一个独立的编译单元,其中将SourceX.CPP和包含的头文件呈现到一个Object文件中。这里有N个独立的东西

这样,如果你不改变通用的标题,那么你就不需要这样做重新编译未修改的源文件。当然,如果你修改了源文件,你必须重新编译它。最后,如果你修改一个公共头文件,那么你就有重新编译包含它的每个源文件。这里我不得不提一下,在编译阶段之前,所有的替换#inlude "filename.ext"行(预处理器指令)使用文件名的确切内容。Ext文件,无论它是什么

在那个阶段,链接是一个不同的问题目标是从这N个对象文件中创建一个文件。(我重复一遍,这是简单的情况)

这是链接:

[ SOURCE1.O + SOURCE2.O + ... + SOURCEN.O ]  --> EXECUTABLE.FILE

将受影响的目标文件想象为一袋值和算法(函数定义)。例如,在袋子的某个地方一定有一个main函数(定义),所以链接器肯定知道什么执行程序时要做的事情

希望你得到它

猜猜会发生什么,如果你把一个全局函数的定义写进头文件,然后你把它包含在两个独立的编译单元中,然后你试着把它们链接起来。

答案:链接器错误-多个定义,因为你可以单独编译它们。

如果MY_HEADER_H只是在mycpp1.cpp中定义的,则头文件将包含在mycpp2.cpp

这个技巧的真正用途是:

header1.h 包括 header2.h
所以当你在mycpp.cpp中包含header1.hheader2.h时,header2.h将被包含两次,如果您没有这样做的话。

如前所述,头文件在每个.cpp文件中包含一次。但是我还想提一下,这个的全部目的是:

#ifndef MY_HEADER_H
#define MY_HEADER_H
// ..
#end if

是为了防止产生问题

mycpp1.cpp

#include "myheader.h"
#include "myheader.h"
// ...

另一件事我有麻烦,当我开始是当你包括你的头文件在多个。cpp文件,并在其中定义全局变量…下面是我解决这个问题的方法…

myheader.h

#ifdef MY_HEADER_H
#define MY_HEADER_H
#ifdef GLOBAL_EXTERN
extern int nGlobalInt;
#else
int nGlobalInt = 282;
#endif
#endif

mycpp1.cpp

#include "myheader.h"
// ...
cout << nGlobalInt;

mycpp2.cpp

#define GLOBAL_EXTERN
#include "myheader.h"
// ...
cout << nGlobalInt;

两个cpp文件将打印282

只包含一次。指令MY_HEADER_H将在第一次包含时被定义,并且随后所有对#include myheader.h的尝试都将无效。

预处理器指令在文件中优先使用。否则,例如,在myheader.h中声明的每个类都将被重新定义。