我理解并非常赞赏将头文件(.h, .hpp)和源文件(.cpp)分开的做法。
然而,许多简单的类可以完全在头文件中定义。我可以在类内定义一些方法,而将其他方法(例如模板方法、内联方法)定义在类下面。
如果我可以在头文件中声明并定义整个类,那么创建一个.cpp文件有何优势呢?(我是否需要这样做?)
我理解并非常赞赏将头文件(.h, .hpp)和源文件(.cpp)分开的做法。
然而,许多简单的类可以完全在头文件中定义。我可以在类内定义一些方法,而将其他方法(例如模板方法、内联方法)定义在类下面。
如果我可以在头文件中声明并定义整个类,那么创建一个.cpp文件有何优势呢?(我是否需要这样做?)
正如已经提到的,编译时间是使用单独的翻译单位的原因之一。特别是如果您有许多核心,并行化可以大幅减少编译时间。另一个原因是,头文件中的非模板类、函数以及变量会导致在不同的翻译单位中包含时出现重复符号。一旦您使用虚函数,内联就不是可行的选项。
您可以使用模板来避免重复符号问题,但除了更长的编译时间外,这还会导致更长的链接时间,因为链接器必须折叠模板实例(请参见https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html)。尽管如此,STL和许多其他仅限头文件的库确实采用了这种方法。
编译速度。将实现与定义分开可以让您灵活修改小代码,而无需重新编译包含该头文件的所有源代码。这是makefile的工作方式,它检测先决条件中的更改。
没有什么能阻止你把所有东西都放在头文件中。但是,如果不这样做,在某些情况下会对项目本身产生各种影响,有时由于不必编译对刚刚进行更改的文件具有依赖关系的所有内容,从而提高可读性并积极提高编译速度。
通常,对于小型类或很少更改的类,几乎没有任何影响。
我想指出的是,随着> c++20和模块的引入,事情将慢慢发生变化,我们将开始看到更多纯粹写在头文件中的代码(如果它们仍然被称为那样)。
尽管如此,这是一个基于观点的问题,没有一个好的答案。