为什么将标题放在单独的目录中?

我知道在C / C ++项目中,将头文件放在诸如include和实现之类的目录中(例如src是很常见的。 我一直在玩弄不同的项目结构,我想知道是否有任何客观原因或仅仅是惯例?

约定是其中一个原因 – 大多数时候,通过有效的抽象,你只关心界面,并希望只是看看标题。

这不是唯一的原因。 如果您的项目是按模块组织的,那么您很可能必须在不同的模块中包含一些标题,并且您希望清除include目录中的其他“噪声”文件。

此外,如果您计划重新分发模块,则可能需要隐藏实现细节。 因此,您只提供标题和二进制文件 – 并且从单个文件夹中分发标题而其他内容则更简单。

还有一个我更喜欢的替代方案 – 公共头文件位于一个单独的文件夹中(这些文件夹包含最小的接口 – 没有任何实现细节可见),私有头文件和实现文件是分开的(可能但不一定在单独的文件夹中) 。

它可以保持文件夹结构更清晰。 标题和源文件明显不同,并且用于不同的事情,因此将它们分开是有意义的。 从这个角度来看,问题基本上与“ 为什么源文件和文档进入不同的文件夹 ”相同? 计算机对于你放在文件夹中的内容以及你不使用的内容是高度不可知的,文件夹 – 大多数情况下 – 只是一个方便的抽象,因为我们人类解析,存储和调用信息的方式。

还有一个事实是头文件即使在你构建之后仍然有用,即如果你正在构建一个库并且有人想要使用该库,他们将需要头文件 – 而不是源文件 – 所以它使捆绑这些头文件 – 抓住bin的东西和include的东西,而不是通过src筛选 – 更容易。

我更喜欢将它们放在同一目录中。 原因:

接口规范文件和实现该接口的源文件属于项目的同一部分。 假设你有subsystemx 。 然后,如果将subsystemx文件放在subsystemx目录中,则subsustemx是自包含的。

如果有很多包含文件,确定你可以做subsystemx/includesubsystemx/source ,但是我认为如果你把class Foo的定义放在foo.hppfoo.cpp你肯定想看到它们(或者至少有可能在目录列表中一起轻松地这样做。 查找与foo相关的所有文件

 ls foo* 

查找所有实施文件:

 ls *.cpp 

查找所有声明文件:

 ls *.hpp 

简单干净。

除了(可论证的?)保持有序,在其他项目等方面有用的有用性,还有一个非常中立和客观的优势:编译时间。

特别是在一个包含大量文件的大项目中,取决于标题的搜索路径(.c / .cpp文件使用#include "headername.h"而不是#include "../../gfx/misc/something/headername.h"并且编译器传递了正确的参数以便能够吞下它”你大大减少了编译器在搜索正确的头时需要扫描的条目数。 由于大多数编译器会针对编译的每个文件单独启动,因此需要读取包含路径上的文件列表并为每个编译文件寻找正确的标头。 如果包含路径上有一堆.c,.o和其他不相关的文件,则在其中查找包含的内容会成比例地延长。

总之,有几个原因:

  • 可维护的代码。
  • 代码设计精良,整洁。
  • 编译时间更快(有时,完成微小的更改)。
  • 更容易隔离接口以备文档等。
  • 可以避免编译时的循环依赖性。
  • 易于审查。

看一下使用C和C ++组织代码文件这篇文章很好地解释了它。