头文件如何工作? [英] How do header files work?

查看:68
本文介绍了头文件如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始自学C ++ ...我正在使用Accelerated C ++。

有些东西没有解释,我一直想知道是怎么样的标题

文件实际上有效。我怀疑它并没有进入它,因为它是,

,正如作者喜欢说的那样,具体实施。如果这是

的情况,编译器通常如何处理它们?我特意使用Linux和gcc

。基本上,我不明白包含的头文件如何与包含头文件中任何内容的

定义的源文件建立连接。这是我的理解我可以将我的头文件完全命名为

与源文件无关,其中包含定义和

包括头文件仍然会定义

函数/什么不可用。怎么样?


谢谢!

解决方案

matthurne写道:

我只是我自己开始学习C ++ ......我正在使用Accelerated C ++。
它没有解释的东西,我一直想知道文件头文件是如何工作的。我怀疑它并没有进入它,因为它是,正如作者喜欢说的那样,具体实施。如果那是
的情况,编译器通常如何处理它们?我特意使用Linux和gcc
。基本上,我不明白包含的头文件如何与源文件建立连接,该源文件具有头文件中任何内容的定义。这是我的理解我可以将我的头文件命名为与包含定义的源文件无关的内容
包括头文件仍然会定义
函数/诸如此类可用。如何?




#include指令只是告诉预处理器去读一个

不同的文件,就好像该文件的内容有已经

包括内联。那里没有其他魔力。您可以#include任何

文件,无论其名称是什么。


matthurneaécrit:

我刚刚开始自己​​学习C ++ ......我正在使用Accelerated C ++。
它没有解释的东西,我一直在想的是标题
文件实际上是如何工作的。我怀疑它并没有进入它,因为它是,正如作者喜欢说的那样,具体实施。如果那是
的情况,编译器通常如何处理它们?我特意使用Linux和gcc
。基本上,我不明白包含的头文件如何与源文件建立连接,该源文件具有头文件中任何内容的定义。这是我的理解我可以将我的头文件命名为与包含定义的源文件无关的内容
包括头文件仍然会定义
函数/诸如此类可用。怎么样?

谢谢!




为了简单起见,你可以更换:


#包含myfile


,逐字内容为myfile


包含文件myfile.h和myfile.cpp for

实例。


用法是定义类型和函数(原型)所以

他们可以是已知的通过#include''将它们放在许多其他源文件中

使用这些函数或类型。


定义void myfunc();时;在一个头文件中,你将它包含在

a源文件中,你只告诉编译器函数myfunc()是

在别处定义。


matthurne发布:

我刚开始自学C ++ ...我正在使用Accelerated C ++。
它有什么东西'解释并且我一直在想,标题文件实际​​上是如何工作的。我怀疑它并没有进入它,因为它是,正如作者喜欢说的那样,具体实施。如果那是
的情况,编译器通常如何处理它们?我特意使用Linux和gcc
。基本上,我不明白包含的头文件如何与源文件建立连接,该源文件具有头文件中任何内容的定义。这是我的理解我可以将我的头文件命名为与包含定义的源文件无关的内容
包括头文件仍然会定义
函数/诸如此类可用。怎么样?

谢谢!



您的C ++程序由源代码文件,AKA模块组成,通常

有一个.cpp扩展名。


每个源代码文件都是单独编译的。

这是一个头文件,Kangaroo.hpp,从@开始符号,结束于

@符号:


@


void Hop(void);


@


现在这里是源代码文件,Chocolate.cpp:

@


#include" Kangaroo.hpp"

int main(无效)

{

Hop();

}


@

甚至在编译源文件之前会发生什么事情

预处理器将Kangaroo.hpp

的全部内容复制并粘贴到您写入的位置#include Kangaroo.hpp。在源代码中

文件Chocolate.cpp。一旦包含了所有的头文件,

你剩下的就是所谓的翻译单元。翻译单位为

" Chocolate.cpp"如下:


@


void Hop(void);


int main(无效)

{

跳();

}


@

然后,这个翻译单元被编译。当它被编译时,你会留下一个带有Object文件的
,它可能是Chocolate.obj。或Chocolate.o。那个'/ b $ b>所有工作都完成了Chocolate.cpp。


你显然会有一个名为源代码的文件; Kangaroo.cpp",在

中,它将是函数void Hop(void)的实际定义。这里是

" Kangaroo.cpp":


@


#include" Kangaroo。 hpp"


void Hop(无效)

{

int k = 4;


k + = 6;

}


@


其中有一个翻译单元,出来其中包含一个Object文件。


所以现在你有两个Object文件:Chocolate.obj和Kangaroo.obj。现在,链接器接管了
。链接器将你所有的Object文件链接成一个

可执行文件。


现在......一个小东西,你*可以*在一个头文件中有一个include语句

档案。这里是'blinds.hpp'的内容:


@


#include" crocodile.hpp"


int Cardiac(无效);


@

现在,假设您有一个包含两者的源代码文件

" blinds.hpp"和crocodile.hpp。两者的内容将被复制到您的源代码文件

中,导致鳄鱼被复制两次。

因此,您将拥有类似以下内容的内容源代码

文件:


struct House

{

int k;

};


struct House

{

int k;

};


显然,第一个问题是你有一个多重定义,

会导致编译错误。不仅如此,如果你有加载和

加载的头文件,并且它们都被包含了几次,你的

程序编译需要更长的时间。这是解决方案:这里是'NiceHeader.hpp'的

内容:


@


#ifndef INC_NICEHEADER_HPP

#define INC_NICEHEADER_HPP


int复发(无效);

#endif


@

现在,你第一次加入NiceHeader.hpp进入你的源代码

文件,它将被复制。但是......后续包括不会做任何事情,因为INC_NICEHEADER_HPP已经被定义了。


每个#define对每个源代码文件都是唯一的。

尽管INC_NICEHEADER_HPP在monkey.cpp中定义,但这并不意味着

它在'resistence.cpp'中定义,因为每个源代码文件都是一个单独的目标文件,它被编译成一个单独的目标文件。然后

链接器将目标文件链接到可执行文件中。因此,你可以拥有

" niceheader.hpp"包含在50个不同的源代码文件中,但是你确保它只会被包含在每个源代码文件中。

另外我觉得我必须提到,请使用以下源代码文件,

" StarFish.cpp":


@


#include iostream


使用命名空间std;


int main(无效)

{


cout<< 帮助!!;


返回0;

}


@

在这里你会看到你不必写std :: cout。在源代码文件中这可以很方便

...

不要在头文件中做到这一点!为什么?因为包含头文件的ENTIRE源代码文件的名称空间属于范围

。同时,如果您在标题库中引用任何内容,

来自头文件,则必须编写std ::"。在它之前。

希望有所帮助。

-JKop


I just started learning C++ on my own...I''m using Accelerated C++.
Something it hasn''t explained and I keep wondering about is how header
files actually work. I suspect it doesn''t get into it because it is,
as the authors love to say, "implementation specific". If that''s the
case, how does the compiler commonly handle them? I use Linux and gcc
specifically. Basically, I don''t understand how a header file being
included makes a connection with the source file that has the
definitions for whatever is in the header file. It is my
understanding I could name my header files something completely
unrelated to the source files which contain the definitions and
including the header files would still make the defined
functions/whatnot usable. How?

Thanks!

解决方案

matthurne wrote:

I just started learning C++ on my own...I''m using Accelerated C++.
Something it hasn''t explained and I keep wondering about is how header
files actually work. I suspect it doesn''t get into it because it is,
as the authors love to say, "implementation specific". If that''s the
case, how does the compiler commonly handle them? I use Linux and gcc
specifically. Basically, I don''t understand how a header file being
included makes a connection with the source file that has the
definitions for whatever is in the header file. It is my
understanding I could name my header files something completely
unrelated to the source files which contain the definitions and
including the header files would still make the defined
functions/whatnot usable. How?



The #include directive just tells the preprocessor to go read a
different file, just as though the contents of that file had been
included inline. There''s no other magic there. You can #include any
file you like, regardless of what its name is.


matthurne a écrit :

I just started learning C++ on my own...I''m using Accelerated C++.
Something it hasn''t explained and I keep wondering about is how header
files actually work. I suspect it doesn''t get into it because it is,
as the authors love to say, "implementation specific". If that''s the
case, how does the compiler commonly handle them? I use Linux and gcc
specifically. Basically, I don''t understand how a header file being
included makes a connection with the source file that has the
definitions for whatever is in the header file. It is my
understanding I could name my header files something completely
unrelated to the source files which contain the definitions and
including the header files would still make the defined
functions/whatnot usable. How?

Thanks!



To make it simple, you could replace:

#include "myfile"

with the verbatim content of "myfile"

There is no link between an include file myfile.h and myfile.cpp for
instance.

The usage is to put definition of type and functions (prototypes) so
that they can be "known" by #include''ing them in many others source file
that use these function or types.

when you define "void myfunc();" in a header file that you include it in
a source file, you only tell the compiler that a function myfunc() is
defined elsewhere.


matthurne posted:

I just started learning C++ on my own...I''m using Accelerated C++.
Something it hasn''t explained and I keep wondering about is how header
files actually work. I suspect it doesn''t get into it because it is,
as the authors love to say, "implementation specific". If that''s the
case, how does the compiler commonly handle them? I use Linux and gcc
specifically. Basically, I don''t understand how a header file being
included makes a connection with the source file that has the
definitions for whatever is in the header file. It is my
understanding I could name my header files something completely
unrelated to the source files which contain the definitions and
including the header files would still make the defined
functions/whatnot usable. How?

Thanks!


Your C++ program is made up of Source Code files, AKA modules, which usually
have a .cpp extension.

Each Source Code file is compiled SEPARATELY.
Here''s a Header file, "Kangaroo.hpp", starting at the @ symbol, ending at
the @ symbol:

@

void Hop(void);

@

Now here''s a Source Code file, "Chocolate.cpp":
@

#include "Kangaroo.hpp"

int main(void)
{
Hop();
}

@
What happens is that even before the Source File is compiled, a thing called
the Preprocessor copies and pastes the entire contents of "Kangaroo.hpp"
right into where you''ve written "#include Kangaroo.hpp" in the Source Code
file "Chocolate.cpp". Once all of the header files have been included,
you''re left with what''s called a translation unit. The translation unit for
"Chocolate.cpp" is as follows:

@

void Hop(void);

int main(void)
{
Hop();
}

@
Then, this translation unit gets compiled. When it''s compiled, you''re left
with an Object file, which may be "Chocolate.obj" or "Chocolate.o". That''s
all the work finished for "Chocolate.cpp".

You''re obviously going to have a Source Code file called "Kangaroo.cpp", in
which will be the actual definition of the function "void Hop(void)". Here''s
"Kangaroo.cpp":

@

#include "Kangaroo.hpp"

void Hop(void)
{
int k = 4;

k+=6;
}

@

Out of this comes a Translation Unit, out of which comes an Object file.

So now you''ve got two Object files: "Chocolate.obj" and "Kangaroo.obj". Now,
the linker takes over. The linker links all your Object files into an
executable.

Now... one little thing, you *can* have an include statement within a header
file. Here''s the contents of "blinds.hpp":

@

#include "crocodile.hpp"

int Cardiac(void);

@
Now, imagine that you have a Source Code file that includes both
"blinds.hpp" and "crocodile.hpp". The contents of both will be copied into
your Source Code file, resulting in Crocodile being copied in twice.
Therefore, you''ll have something like the following in your Source Code
file:

struct House
{
int k;
};

struct House
{
int k;
};

Obviously, the first problem is that you''ve got a "Multiple Definition",
which will result in a compile error. Not only that, if you have loads and
loads of header files, and they all get included a couple of times, your
program would take much longer to compile. Here''s the solution: Here''s the
contents of "NiceHeader.hpp":

@

#ifndef INC_NICEHEADER_HPP
#define INC_NICEHEADER_HPP

int Relapse(void);
#endif

@
Now, the very first time you include "NiceHeader.hpp" into your Source Code
file, it will be copypasted in. But... subsequent includes won''t do
anything, because INC_NICEHEADER_HPP is already defined.

Each #define is unique to each Source Code file.
Even though INC_NICEHEADER_HPP is defined in "monkey.cpp", that doesn''t mean
it''s defined in "resistence.cpp", because each Source Code file is a
seperate entitiy, which gets compiled into a separate object file. Then the
linker links the object files into an executable. Therefore, you can have
"niceheader.hpp" included into 50 different Source Code files, but you''re
guaranteed that it will only be included into each Source Code file ONCE.
Another thing I feel I must mention, take the following Source Code file,
"StarFish.cpp":

@

#include "iostream"

using namespace std;

int main(void)
{

cout << "Help!!";

return 0;
}

@
Here you''ll see that you don''t have to write "std::cout". This can be handy
in a Source Code file...
DON''T DO IT IN A HEADER FILE!! Why? Because the namespace comes into scope
for the ENTIRE Source Code file into which the header file has been
included. Concordantly, if you refer to anything in the standard library,
from within a header file, you must write "std::" before it.
Hope that helps.
-JKop


这篇关于头文件如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆