C++包含文件
C++ Include files
我知道在头文件中提供定义允许其他文件引用它们,然后链接器将所有对象文件添加在一起,稍后提供定义。
这只是为了让我们可以在其他库中的其他地方重用实现吗?
如果我们不使用头文件或滥用它们,并将所有代码都放在其中,即完整的实现会发生什么?编译每个文件时会花费更长的时间吗?因为完整的定义需要在对等文件的基础上编译?它会不会导致链接器出现问题,因为同一实现会有多个编译版本?
如何使用模板?
布莱尔
每当新的编译目标包括头文件时,放置在头文件中的任何代码都会被编译,所以至少是的,编译时间会更长。不过,一般来说,这并不是什么大问题。
假设你有这个标题:
int f_header() {
return 0;
}
这些源文件:
/* a.cpp */
#include "myheader.h"
int f_a() {
return f_header();
}
/* b.cpp */
#include "myheader.h"
int f_b() {
return f_header();
}
现在,当您编译这些源中的每一个时,编译就会成功。但是,当您链接程序时,链接器将失败,因为您将提供两次函数f_header()
。
模板是一种特殊情况,因为它们实际上不是代码,而是为基于不同类型生成的代码提供了一个模板。尽管当多个源文件使用相同类型的文件时会出现重复,但编译器能够为您处理这种特殊情况。
拆分源文件和头文件中的代码在历史上或多或少是必需的。它允许编译器单独编译大型项目的代码单元,因为整个项目太大,无法同时编译。
它还允许缓存未更改的编译单元,这进一步缩短了编译时间。
因此,从技术上讲,编译器可以看到一整套不同的编译单元。如果您提供了同一定义的多个实现,编译器就无法告诉您。但是,一旦链接器将编译后的单元打包为一个可执行文件,它就会被它绊倒。
今天,像C#或Java这样的"现代"语言摆脱了这种历史限制。但是C++是一种复杂的语言,即使对于编译器来说也是如此,所以这些优势在某种程度上仍然是相关的。
编译器一次编译一个文件。编译器正在解析的源文件可能包括其他文件,但在预编译阶段,所有这些包含的文件都被"展平"为单个源,编译器"看到"一个单独的代码实体。
由于以上原因,对于编译器来说,代码是在.cpp文件中还是在.h文件中并不重要,因为编译器不进行区分。但是,如果一些函数定义或变量定义在.h文件中,则问题会在链接阶段出现。
链接器看不到源文件,但它看到了对象文件(.obj),这是编译器生成的结果。链接器知道每个对象文件中的每个函数和每个变量,链接器的工作是将它们绑定(或链接)在一个可执行文件中。如果在不同的对象文件中有几个具有相同名称的变量或函数,链接器将不知道该如何处理它们,并且它将声明一个错误。可以通过一个选项强制链接器忽略所有额外的变量和函数,但该选项不能轻易使用。两个同名的函数实际上可能完全不同,忽略其中一个会导致各种错误。
另一方面,模板根本不是函数。它们是实际功能的蓝图。当编译器遇到模板时,不会发生实质性的事情。只有当模板被实例化为实际函数时,编译器才会生成这样的函数。正因为如此,模板可以驻留在头文件中。
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- C++文件包含多行
- CMake 如何强制third_party库将项目文件包含在当前项目源目录中?
- 是否可以将要"ShellExecute"的文件包含在 dll 中?如果是这样,"ShellExecute"中的文件位置应该是什么?
- C++ 逐行从文件(包含空格)读取数据
- 在 C++ 中,.h 文件包含文件但不起作用
- 生成的资源文件包含奇怪的包含文件
- 可变参数类的文件包含问题
- 为什么文件命令声明可执行文件包含"debug_info"
- 可以将标头文件包含在多个源文件中,而无需重复保护
- 为什么将.HPP文件包含在.h文件中
- Qt C++:将所有库文件包含在项目文件夹中
- 有条件地将文件包含在C++标头中
- 将多个原型文件包含在一个项目中会导致protobuf_AssignDescriptorsOnce()已经有一个主体
- 有没有办法将文件包含在C++中的所有项目文件中
- 将外部.asm文件包含到C++代码中
- 什么是"pch.h",为什么需要将其作为第一个头文件包含在内?
- 该头文件包含DirectX 12中的ThrowIfFailed()
- QT C :函数的多个定义当Header文件包含在MainWindow.h中时
- QT创建者错误地处理标头文件包含来自Directory