gpt4 book ai didi

c++ - 为什么在 .h 文件中使用 #ifndef CLASS_H 和 #define CLASS_H 而不是在 .cpp 中?

转载 作者:IT老高 更新时间:2023-10-28 11:34:07 27 4
gpt4 key购买 nike

我一直看到人们写作

类.h

#ifndef CLASS_H
#define CLASS_H

//blah blah blah

#endif

问题是,他们为什么不对包含类函数定义的 .cpp 文件也这样做?

假设我有 main.cpp,而 main.cpp 包含 class.hclass.h 文件没有include 任何东西,那么main.cpp 怎么知道class.cpp ?

最佳答案

首先,解决您的第一个问题:

当您在 .h 文件中看到此内容时:

#ifndef FILE_H
#define FILE_H

/* ... Declarations etc here ... */

#endif

这是一种防止头文件被多次包含的预处理器技术,由于各种原因,这可能会出现问题。在您的项目编译期间,每个 .cpp 文件(通常)都会被编译。简单来说,这意味着编译器会获取你的 .cpp 文件,通过它打开任何 #included 文件,将它们全部连接成一个巨大的文本文件,然后执行语法分析,最后将其转换为一些中间代码,优化/执行其他任务,最后为目标架构生成汇编输出。因此,如果一个文件在一个 .cpp 文件下多次被 #included ,编译器将附加其文件内容两次,所以如果该文件中有定义,你会得到一个编译器错误,告诉你你重新定义了一个变量。当编译过程中的预处理器步骤处理文件时,第一次到达其内容时,前两行将检查是否为预处理器定义了 FILE_H。如果不是,它将定义 FILE_H 并继续处理它与 #endif 指令之间的代码。下次预处理器看到该文件的内容时,对 FILE_H 的检查将是错误的,因此它会立即向下扫描到 #endif 并在它之后继续。这样可以防止重新定义错误。

并解决您的第二个问题:

在 C++ 编程中,我们通常将开发分为两种文件类型。一种是扩展名为 .h,我们称之为“头文件”。它们通常提供函数、类、结构、全局变量、typedef、预处理宏和定义等的声明。基本上,它们只是为您提供有关代码的信息。然后我们有 .cpp 扩展名,我们称之为“代码文件”。这将为那些函数、类成员、任何需要定义的结构成员、全局变量等提供定义。因此 .h 文件声明代码,而 .cpp 文件实现该声明。出于这个原因,我们通常在编译期间将每个 .cpp 文件编译成一个对象,然后链接这些对象(因为您几乎从未见过一个 .cpp 文件包含另一个 .cpp 文件)。

如何解决这些外部因素是链接器的工作。当您的编译器处理 ma​​in.cpp 时,它会通过包含 class.h 来获取 class.cpp 中代码的声明。它只需要知道这些函数或变量是什么样的(这是声明给你的)。因此它会将您的 ma​​in.cpp 文件编译成某个目标文件(称为 ma​​in.obj)。同样,class.cpp 被编译成 class.obj 文件。为了生成最终的可执行文件,调用链接器将这两个目标文件链接在一起。对于任何未解析的外部变量或函数,编译器将在访问发生的地方放置一个 stub 。然后,链接器将获取此 stub 并在另一个列出的目标文件中查找代码或变量,如果找到,它将两个目标文件中的代码组合到一个输出文件中,并将 stub 替换为函数的最终位置或多变的。这样,您在 main.cpp 中的代码可以调用函数并使用 class.cpp 中的变量,当且仅当它们在 class.h 中声明时。

我希望这会有所帮助。

关于c++ - 为什么在 .h 文件中使用 #ifndef CLASS_H 和 #define CLASS_H 而不是在 .cpp 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3246803/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com