在头文件中实现小功能,包括在同一项目的两个不同文件中

Implementing small functions in a header file, including in two different files in the same project

来自 learncpp.com 关于是否在头文件中实现函数的引用:

  1. For classes used in only one file that aren’t generally reusable, define them directly in the single .cpp file they’re used in.
  2. For classes used in multiple files, or intended for general reuse, define them in a .h file that has the same name as the class.
  3. Trivial member functions (trivial constructors or destructors, access functions, etc…) can be defined inside the class.
  4. Non-trivial member functions should be defined in a .cpp file that has the same name as the class.

假设我按照#3 的建议,在 my_class.h 文件中实现了一些小方法 my_class::f,但我将更大的方法留在 my_class.cpp 中实现。如果我在同一项目的两个不同 .cpp 文件中包含 my_class.h,则链接器将看到 my_class::f 的两个(相同)定义。 (这不是由头部防护解决的。)我知道一些链接器足够聪明可以容忍这个(尽管我听说它会花费额外的时间)。我的问题是:

Do you think they recommend #3 because it is uncommon to include the same .h file twice across a project, or because the linker can be relied upon to ignore the duplicate definition, and will not waste too much time doing so?

在推荐#3中写着

Trivial member functions (trivial constructors or destructors, access functions, etc…) can be defined inside the class.

class中定义的成员函数是内联函数。所以在几个编译单元中包含header是没有问题的。

I understand that some linkers are smart enough to tolerate this

所有 符合标准的链接器容许多个相同的内联函数定义。

linker can be relied upon to ignore the duplicate definition

是的。

and will not waste too much time doing so?

我不希望链接器浪费大量时间。

但是,内联函数通常必须针对使用它们的每个翻译单元进行编译。如果它是一个特别复杂的函数,那么编译器(而不是链接器)最终可能会浪费大量时间。这就是本教程建议仅内联定义简单函数的部分原因。

遵循(隐含的)建议(不是 定义 non-trivial 内联函数)的另一个原因是 non-trivial 函数会引起变化,并且修改头文件作为包含这些头文件的文件的更改传播。 Non-inline 函数可以将 re-compilation 时间缩短到整个编译时间的一小部分,因为不需要重复编译,并且在更改时也不会导致其他翻译单元被编译。