什么时候不应该将我的代码拆分成头文件和源文件?

时间:2011-10-18 10:23:41

标签: c++ coding-style

我知道这可能非常主观,但是当代码没有必要分成两个文件时,是否有任何通用规则?

例如,类是非常小的,还是文件只包含一些全局定义或静态函数?此外,在这些情况下,单个文件应该是.cpp文件还是.h文件?

5 个答案:

答案 0 :(得分:7)

在技术方面,每当您需要遵守一个定义规则时,您必须将声明与定义分开,因为您需要在多个翻译单元中多次包含声明,但您必须只提供一个单一的定义。

在美学方面,答案可能是“总是”或“系统地”。在任何情况下,您应该始终为每个逻辑代码单元(例如一个类或一个函数集合)提供标题; source 文件可能是可选的,具体取决于您是否内联定义了所有内容(免除ODR),或者您是否有模板库。

作为一种元策略,您应该尽可能地将编译单元解耦,以便您只能以细粒度的方式包含所需的内容。这使您的项目得以增长,而不会使编译时间变得难以忍受,并且使得在其他项目中重用代码变得更加容易。

答案 1 :(得分:3)

我赞成将代码放在.hpp文件中,但由于以下任何原因,我经常被迫将实现放在.cpp中:

  1. 缩短构建时间。这是使用.cpp文件的首要原因...以及您在.hpp文件中找到的大多数代码的原因都很简单。当实现发生更改时,您不希望重建包含它的每个.cpp。
  2. 当函数的链接很重要时。例如,如果将函数导出为库(例如DLL)函数,则选择要存在的单个编译单元非常重要。或者对于静态/全局实例。这对于分发DLL的导入标头也很重要。
  3. 当您希望在分发库时隐藏实现细节
  4. 定义和声明不相同。关于参数的常量,可能就是这种情况。
  5. 您想要了解.hpp文件中接口的“干净”概述。我发现使用现代代码工具并且越来越熟悉javascript / C#/ inline C ++等单代码文件语言,这不是一个强有力的论据。
  6. 您明确不希望将函数声明为inline。虽然,没关系;如果想要,优化编译器可能会内联。
  7. 将代码内联在.hpp文件中有逻辑动机:

    1. 为什么有两个文件?
    2. 复制声明/功能标题是不必要的维护,并且感觉多余。我们有代码分析工具来显示接口。
    3. 内联/模板代码必须放在标题中,其他代码放在.cpp中的概念是任意的。如果我们被迫将内联代码放在.hpp文件中,这没关系,那为什么不将所有代码放在.hpp文件中呢?
    4. 我很确定,但是单独的.cpp和.hpp文件的传统远远强于推理。

答案 2 :(得分:0)

  

我知道这可能很主观,但是有没有一般规则   对于不需要将代码拆分为两个的情况   文件?

尽可能将代码拆分为标题和源代码。

通常,在下一种情况下不应该这样做:

  • 代码由模板类和函数组成(除非你 显式实例化源文件中的模板)
  • 标题仅包含内联函数
  

单个文件应该是.cpp文件还是.h文件?

应该是头文件(.h)。

答案 3 :(得分:0)

我使用的规则如下:

  

每当您可以将代码放入cpp文件时,请执行此操作。

原因很多:

  • 头文件作为基本文档。最好不要用代码来混淆它们。
  • 如果您愿意,也可以在某些地方使用pimpls,原因如上。
  • 减少了编译时间:
    • 每当您更改.cpp时,只会重新编译此文件。
    • 每当包含标头时,它只包含所需的最少代码
  • 通过查看包含哪些标题,您可以更轻松地评估代码的哪一部分取决于哪个部分。这一点要求我的另一条规则:
  

每当你可以转发声明一个类而不是包含一个标题时,就这样做。

这样,.cpp文件会在源的各个部分之间传递依赖关系信息。它还可以缩短构建时间。

答案 4 :(得分:0)

  

我知道这可能非常主观,但是当代码没有必要分成两个文件时,是否有任何通用规则?

并不总是主观的;你将有很好的理由在大型项目中将它们分开。进入分离它们的实践是很好的,并且学习什么时候并且不适合将定义与声明分开。如果不知道代码库会变得多么复杂,就很难回答你的问题。

  

例如,该类非常小

一般来说,分开它们仍然不是一个坏主意。

  

或者如果文件只包含一些全局定义

除非必要,否则标题不应包含需要静态构造的全局定义。

  

或静态函数?

这些不属于C ++中的任何地方。使用内联或匿名命名空间。如果你的意思是在一个类的主体内,“它取决于指令数,如果你希望它将被内联”。

  

此外,在这些情况下,单个文件应该是.cpp文件还是.h文件?

单个文件应该是标题。理由:你不应该#include cpp文件。

不要忘记,模块间(也就是链接时间)优化越来越好。

C ++编译时间很长,事后修复它非常非常耗费时间。我建议您在构建时间和依赖项爆炸之前进入使用cpp文件的实践。