头文件如何连接到相应的.cpp文件?
How is the header file connected to the corresponding .cpp file?
根据我所阅读和理解的内容,源文件中的#include
指令,例如:main.cpp
,只是将包含文件的内容复制到.cpp
。因此,当我包含一个头文件时,例如:yum.h
,yum.h
中的所有语句都复制到main.cpp
中。
头文件将只有声明,实际定义将在相应的.cpp
文件中,如yum.cpp
。
那么,在编译main.cpp
时,编译器如何知道在yum.cpp
中查找yum.h
中提到的任何函数的定义?编译器如何知道也遵守yum.cpp
文件,因为main.cpp
文件或yum.h
中都没有引用它。
另外,为什么yum.h
应该包含在yum.cpp
中?
这听起来像是一个愚蠢的问题。我是 OOP 和 C++ 的初学者,只是想了解正在发生的事情。
简短的回答:标头与其实现之间没有关系。一个可以存在而没有另一个,或者可以将两个放在名称不相关的文件中。
在编译
main.cpp
编译器如何知道查找yum.cpp
中yum.h
中提到的任何函数的定义?
编译器不知道。每次它看到对在yum.h
或任何其他头文件中声明的内容的引用时,它都会留意相应的定义。
如果在编译器到达翻译单元末尾时定义不存在,它将不满意的引用写入其main.o
输出,并注意它们的来源。这称为符号表。
然后编译器编译yum.cpp
,从其中的yum.h
中找到定义,并将它们的位置写入yum.o
的符号表中。
处理完所有cpp
文件后,链接器将获取所有.o
文件,并从中生成组合符号表。如果保留未满足的引用,则会发出错误。否则,它将main.o
中的引用与yum.o
中的相应符号链接,完成该过程。
考虑一个例子:假设yum.h
声明了一个全局变量int yum = 0
yum.cpp
中定义的,main.cpp
打印该变量。编译器生成main.o
符号表,上面写着"我需要int yum
在地址 1234 的定义",yum.o
文件的符号表说"我在地址 9876 处有int yum
"。链接器通过将 9876 放在地址 1234 中来匹配"我需要"和"我有"。
编译器不需要在其他代码文件中查找任何内容。
编译的结果是一个对象文件,该文件包含其他代码文件中定义的任何内容的占位符。为了制作这些占位符,编译器只需要合适的标头(声明、原型等)提供的信息。
填写占位符的步骤是链接器的工作,链接器在理论上是独立于编译器的工具。("理论上"如"可以是单个工具,表现得像两个单独的工具。
将带有声明的标头包含在执行实现(全部或部分声明的内容)的代码文件中的原因是一种广泛传播的最佳实践,因为它允许编译器在实现和声明不匹配时进行投诉。
那么在编译main时.cpp编译器如何知道在yum.cpp中查找yum.h中提到的任何函数的定义?
编译器没有。当它生成目标文件(这是编译的结果)时,它会在那里说 - 调用某某函数。然后是链接过程,其中所有对象文件和库链接在一起以生成可执行文件。当链接器看到所有对象文件并库时,它知道在哪里可以找到该函数(如果找不到它,则产生错误)。
即编译器如何知道也遵守 yum.cpp 文件,因为在 main.cpp 文件或 yum.h 文件中都没有引用它。
编译器也不知道这一点。程序员的工作是告诉编译器将所有必要的源文件编译为对象文件,并将它们全部传递给链接器。它可以在IDE中完成,可以对您隐藏,或者您可能必须使用实用程序make
手动执行此操作。
还有为什么 yum.h 应该包含在 yum 中.cpp
当你编译C++程序时,你通常有类和它们的方法。为了能够在其他源文件中使用类,它的定义必须在那里可见,所以它转到一个标题。方法在文件中实现时也必须首先在类.cpp声明,以便.cpp必须包含它的标头。即使对于独立函数,让编译器将标头中的签名与实现中的签名匹配也更干净。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 命名空间中具有.h和.cpp文件的类
- 为什么我的主文件.cpp不打印头文件中的任何内容
- 生成文件错误 - 找不到文件 - *.cpp
- 如何在文件.cpp gtkmm中声明小部件
- 没有实现文件(.cpp)的派生类
- 如何使用"CMakeLists.txt"中的add_library将整个文件(.cpp,.h等)包含在目录中
- 如何在Linux / Windows操作系统上使用文件*.cpp一步编译下面的代码
- 关于 Linux .so 文件无法链接到主文件.cpp文件
- 文件.cpp从Windows到Linux
- Ubuntu C++ 编译器错误: g++: 错误: 文件.cpp: 没有这样的文件或目录
- 如何将文件.cpp编译为本机编译
- 使用模板类时,似乎无法包含除 main 以外的任何 cpp 文件.cpp
- 无法编译C++文件.cpp。C++98模式
- 为什么C++头文件不需要包含实现文件 (.cpp)
- 如何访问位于独立文件(.cpp)中的非成员函数
- 如何在Visual Studio Code中通过键盘快捷键切换头文件/cpp文件
- 如何将数据从stringstream写入文件(CPP)
- 为什么filestream不把空白写入文件cpp ?