当我包含头文件时,让我们说,
//myheader.h
#ifndef MY_HEADER_H
#define MY_HEADER_H
//....
#endif
成,
//mycpp1.cpp
#include "myheader.h"
我被告知的是,当mycpp1.cpp包含myheader.h时,MY_HEADER_H
被定义,因此任何再次包含它的尝试都将导致错误。
现在,如果我想将它包含在mycpp2.cpp中。
//mpcpp2.cpp
#include "myheader.h"
它是否会被包含在内,或者它是否在第一次被包含时使用相同的声明?
答案 0 :(得分:6)
每个文件的预处理器定义是分开的。因此,如果将#include
myheader.h分成两个单独的.cpp文件,它将被包含两次,而不是一次。一个.cpp。
答案 1 :(得分:4)
预处理器定义是当前编译单元的本地。
当然有复杂的情况,但重点是:
尝试将.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"
行(预处理程序指令)
以及filename.ext文件的确切内容,无论它是什么。
然后在那个阶段,链接是一个不同的问题 目标是从N个目标文件创建一个单独的文件。 (我再说一遍,这是一个简单的例子)
这是链接:
[ SOURCE1.O + SOURCE2.O + ... + SOURCEN.O ] --> EXECUTABLE.FILE
想象一下受影响的对象文件作为一包价值和
算法(函数定义)。例如,包里的某个地方必须有一个
main
函数(定义),因此链接器肯定会知道什么
执行程序时要执行的操作。
希望你明白了
猜猜如果将全局函数的定义写入头文件中会发生什么, 然后将它包含在两个单独的编译单元中,然后尝试链接它们。
答案:链接器错误 - 多个定义,因为您可以单独编译它们。
答案 2 :(得分:3)
如果 MY_HEADER_H 刚刚在mycpp1.cpp中定义,则头文件将包含在mycpp2.cpp中
真正的诀窍是:
header1.h 包含 header2.h 因此,当您在mycpp.cpp中包含 header1.h 和 header2.h 时, header2.h 如果你没有做到这一点,将会被包括两次。
答案 3 :(得分:1)
正如其他人所说,每个.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
答案 4 :(得分:-1)
它只会包含一次。指令MY_HEADER_H将在第一次包含时定义,随后对#include
myheader.h的所有尝试都将无效。
预处理程序指令优先于文件。否则,例如,myheader.h中声明的每个类都将被重新定义。