繁体   English   中英

为什么我要编译 2 个 C/++ 源文件而不是使用 header 文件?

[英]Why would I compile 2 C/++ source files instead of using a header file?

我最近开始学习 makefile,我正在观看的视频包括两个源文件和一个 header 文件的编译。 class 在 header 文件中定义,该文件包含在两个源文件中。 class 的方法在一个源文件中定义,并在第二个源文件 (main.cpp) 中调用。 为什么我需要有 2 个源文件 (.c/.cpp)?

每次对 header 文件进行任何更改时,都必须重新编译包含它的每个文件,但如果更改源文件,则只需重新编译该源文件。

在处理非平凡大小的项目时,这可以显着减少编译时间。 由于您的大部分工作通常是在实现方面完成的,因此对 header 文件的修改不如对源文件的修改频繁,因此大多数重新编译都将本地化。

出于可导航性的原因,您还需要将源代码拆分为单独的文件。 处理一个超过 2000 行的源文件比处理 10 个大约 200 行的文件要麻烦得多。 当版本控制启动并且您在团队中工作时,这一点更为重要,因为这样可以减少合并冲突。

想象一下,如果 Chrome 只是一个单一的.cpp文件。 即使对它进行最微不足道的更改也需要重新编译整个东西,即使在装备精良的机器上也需要 6-12 个小时。 相比之下,编译单个源文件并重新链接只需几分钟。

在实践中,每个源文件通常会有一个 class 和相应的 header 文件。 函数在逻辑上组合成集合,每个集合在它们自己的一对头文件/源文件中。

人类的大脑一次无法容纳太多信息,因此我们将事物分割成更小的、合乎逻辑且连贯的片段。

好的。 因此,一个 main.cpp 包含程序中的数十个或数百个或数千个文件,所有文件都在合理大小的 header 文件中实现,每个文件涵盖一个概念或聚合更多头文件,如果一个概念过于宽泛而难以描述1在单个 header 中。 问题解决了,对吧? 是的。 但这只是一个问题。

资源消耗呢?

阅读编译/链接过程如何工作? 在继续之前。

在预处理期间,每个包含语句都将替换为包含文件的内容。 结果是一个输入编译器的庞大文件。 这占用了大量的 memory。 此外,如果一个文件包含所有内容作为标题,那么每次您进行更改时,无论多么小,都需要构建这个文件。 它将包括项目的标头价值,并且一个更改会导致所有文件都被重新编译。 这变得非常耗时。

Memory 越来越便宜,因此限制第一个资源并不像 1970 年代所有这些都被发明的时候那么重要2 还时不时抬起它丑陋的脑袋。 这就是为什么我在一台又大又胖的 PC 上交叉编译而不是直接在 Raspberry Pi 上构建代码的原因。

时间不会变得更便宜。 从来没有,永远不会。

但是,如果您遵循最佳实践并且标头包含一个接口(它做什么)而不是一个实现(它是如何做的),您会发现 header 没有太大变化。 大部分时间发生变化的是实现文件中的操作方法细节。 一个小的更改仅限于提供该更改行为的一个实现文件。 可能这是唯一需要重新编译的文件。 这是从每次每个文件到每次一两个文件的巨大改进。

在界面发生变化的极少数情况下,你会接受它。

1因为这就是代码:对行为的描述。 它不是计算机要执行的指令列表——这是编译器的输出——它是对程序行为的描述。 编译器的工作是将您的描述转换为指令。

2这也解释了为什么用最近创建的语言构建要简单得多3 在 1/2 K 内存和千赫频率的 CPU 的辉煌岁月里,他们没有留下任何包袱。 他们也从很多错误中吸取了教训。

3对于最终用户,无论如何。 现代构建系统的后端是一些疯狂的代码,伙计。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM