为什么将函数体放置在单独的源代码文件而不是标题中的C/C 中

Why are function bodies in C/C++ placed in separate source code files instead of headers?

本文关键字:标题 文件 源代码 函数体 单独 为什么      更新时间:2023-10-16

例如,当我在C 中定义类文件时,我总是将功能体放在类Header Files(.H)中,以及类定义。源代码文件(.cpp)是具有MAIM()函数的一个。现在是在Pro C 程序员中通常完成的,还是遵循单独的标头/源代码文件的约定。

对于本机C,我确实注意到然后在GCC中完成(当然,对于Windows的Visual Studio中的标题)。

那么这只是惯例吗?还是这样的原因?

功能主体被放入.cpp文件中以实现以下内容:

  1. 进行编译器解析并仅编译一次,而不是强迫它们再次编译它们,一次又一次地包括标头文件。此外,如果以标头实现为例,稍后将必须检测并消除到达不同对象文件中的相同的外部链接函数。

    许多现代编译器实施的标题预译机可能会大大减少重复重复同一标头文件所需的浪费努力,但它们并没有完全消除问题。

  2. 向模块或库的未来用户隐藏这些功能的实现。实施隐藏技术有助于执行某些编程学科,从而减少模块之间的寄生相互依赖性,从而导致更清洁的代码和更快的编译时间。

    我什至会说,即使用户可以访问库的完整源代码(即,没有什么真正"隐藏"的库,也可以通过标头文件可见的清洁分离,而不是假设的东西可见对图书馆的自我示例属性有益(尽管在仅标题库中也可以实现这种分离)。

  3. 使外界的一些功能"不可见"(即内部链接,与您的示例不立即与类方法相关)。

  4. 位于特定翻译单元中的非内部功能可以接受某些与上下文有关的优化。例如,具有相同尾部部分的两个不同功能最终可以"共享"实现这些相同尾巴的机器代码。

    在标头文件中声明为内联的函数在不同的翻译单元中多次编译(即在不同的上下文中),稍后必须被链接器删除,这使得(如果可能的话)更难利用这种优势优化机会。

  5. 我可能错过的其他原因。

它是一个约定,但也取决于特定需求。例如,如果您正在编写希望该功能快速(内联)的库,并且正在设计库以使其他人用作简单的header only库,则可以在header文件中写入所有代码(s)本身。

另一方面;如果您正在编写将静态或动态链接的库,并且您正在尝试将内部对象数据封装在用户中。您的功能 - 类成员函数等,将以他们应执行的操作来编写,以便在库代码的用户中不必担心该部分的实际实现详细信息是隐藏的。他们需要了解的有关您的功能和课程所需的只是他们的界面。以这种方式,您将同时拥有标题文件和实现文件。

如果您将函数定义定义及其声明以及它们的声明,它们将是内联的,应该运行速度更快,但是您的可执行文件将更大,并且每次都必须汇编。实施详细信息也暴露于用户。

如果将函数定义定义放在标题相关的代码文件中,它们不会是内联的,您的代码将较小,它可能会慢一点,但是您只需要将它们编译一次即可。实现细节被隐藏并从用户中抽象出来。

绝对没有理由将功能体放在'c'中的标题文件中。如果标题文件包含在多个" C"文件中,则将迫使编译器多次定义函数。如果该函数为"静态",则该程序中将有多个副本,如果它是全局,则链接器将抱怨。

类似的推理是针对C 的。该类的"内联"成员和一些模板实现。

如果您在" CPP"文件中定义了临时类,则可以在此处定义并具有在类内定义的功能体。