我正在开发一个基本的游戏引擎,一直遵循建议只包含我需要的东西。我注意到,在某些地方,我包含了大量来自某些模块的东西,比如数学或渲染。然后,人们应该定期维护这些长列表,这样它实际上就只是人们需要的东西,不多不少。
但是包含我不需要的东西真的有那么严重吗?难道我不能只包含使用渲染和数学内容的 Render.hpp 和 Math.hpp 吗?而不是分别寻找每个小组件的所有标题并维护一个很长的包含列表?专业建议是始终只包含我需要的内容,但我使用的大多数库都是通过一个包含或单独包含它们的主要模块来包含的,而不是逐个包含它们的所有标题。
包含超出我需要的内容是否真的会造成如此混乱并增加编译/解析时间?
在我看来,这个问题的答案取决于我们谈论的是.cpp 还是.h 文件。
对于 .cpp 文件,包含超过严格必要内容的唯一缺点是增加编译时间。根据您的项目和包含的文件,影响范围从微不足道到非常大。
如果我们谈论的是头文件,那就完全是另一回事了。如果你在这里包含不需要的文件,你可能会引入不需要的依赖项,而这可能会因更多原因而变得糟糕。
例如,假设您有以下文件:
等等,然后你决定合并所有标题:
common.h
并在所有.cpp 文件中使用它,而不是单独包含。现在,突然
a.cpp
不再需要依赖some_lib_2
并且b.cpp
已经依赖some_lib_1
。这可能需要更改您的构建配置并增加未来不同任务的复杂性,如单元测试、重构等。
这是一条建议,不要盲目应用它,了解它存在的原因,这样你就不会走极端,比如过度使用面向对象编程和设计模式,这导致许多公司的代码库非常糟糕。喝水是好习惯,但喝太多会导致死亡。
包含更多标头的缺点是增加了编译时间(以及 C 中的命名空间污染,或者如果您误用了
using namespace
)。这仅在大型项目或巨大依赖项(例如<Windows.h>
及其功能排除#define
)中才会出现。我想说的是,导入与您的代码无关的东西是不好的做法,可能会违反逻辑分离,后端不可知的游戏引擎永远不会导入后端特定部分之外的 D3D12 或 Vulkan 标头。根据您的说法,看起来拥有多个带有大量包含项的主题头文件将使您的项目更易于维护并且麻烦更少,这种权衡可能值得增加编译时间,特别是如果您花费更多时间来确定确切的头文件列表,并且在维护此列表时出错的风险更高。
所有大型游戏引擎实际上都有一些(如果不是一个的话)
"Math.h"
包含所有常规线性代数和它们使用的更多内容的模块。它们的各种模块也一样。您已经在问题中将Math和Render确定为可能值得拥有自己的标头的模块,您可以为这些模块中常用的 s 创建-internal.h变体#include
,这些变体不应公开暴露给使用它的其他模块。所以。在 C 和 C++ 中,
#include
实际上是对所包含文件内容的复制粘贴。#include
通常使用仅包含 s 的文件来创建主题标题。您应该考虑通常包含的内容并为每个标题定义全面的范围,以保持项目的可维护性。最终重要的是健全性(参见我关于 Vulkan/D3D12 的示例),并且您花费更少的时间来解决问题、等待和为您的
#include
s 感到痛苦。