为什么C/C++中的函数体放在单独的源代码文件中而不是头文件中?

1aaf6o9v  于 8个月前  发布在  C/C++
关注(0)|答案(3)|浏览(110)

例如,当我在C中定义类文件时,我总是将函数体与类定义沿着放在类头文件(.h)中。源代码文件(.cpp)是带有main()函数的文件。现在,这在pro c程序员中是普遍这样做的,还是他们遵循单独的头/源代码文件的惯例。
至于原生C,我注意到它是在GCC中完成的(当然还有Visual Studio for Windows中的头文件)。
所以这只是一个惯例?还是有什么原因

7hiiyaii

7hiiyaii1#

函数体被放置到.cpp文件中以实现以下功能:
1.使编译器只解析和编译它们一次,而不是强迫它在包含头文件的任何地方一次又一次地编译它们。此外,在头实现的情况下,链接器稍后将不得不检测和消除到达不同目标文件的相同外部链接函数。
许多现代编译器实现的头文件预编译功能可能会显著减少重复重新编译同一个头文件所需的工作量,但它们并不能完全消除这个问题。
1.对模块或库的未来用户隐藏这些函数的实现。实现隐藏技术有助于执行某些编程规则,这减少了模块之间的寄生相互依赖性,从而导致更清晰的代码和更快的编译时间。
我甚至会说,即使用户可以访问库的完整源代码(即,没有什么是真正“隐藏”的),在应该通过头文件可见的内容和不应该可见的内容之间的清晰分离对库的自文档化属性是有益的(尽管这种分离在仅头文件的库中也是可以实现的)。
1.为了使某些功能对外部世界“不可见”(即,内部链接,与类方法的示例不直接相关)。
1.驻留在特定翻译单元中的非内联函数可以进行某些上下文相关的优化。例如,具有相同尾部的两个不同函数最终可以“共享”实现这些相同尾部的机器代码。
在头文件中声明为内联的函数在不同的翻译单元中被编译多次(即,在不同的上下文中),并且随后必须由链接器消除,这使得利用这种优化机会更加困难(如果可能的话)。
1.其他我可能忽略的原因。

wmtdaxz3

wmtdaxz32#

这是一种惯例,但也取决于具体需要。例如,如果你正在编写一个库,你希望它的功能是快速的(内联的),并且你正在设计一个简单的header only库供其他人使用,那么你可以在头文件本身中编写所有代码。
另一方面;如果你正在编写一个库,它将被静态或动态地链接,并且你试图封装来自用户的内部对象数据。你的函数-类成员函数等等。将以这样的方式编写,它们做它们应该做的事情,以便库代码的用户不必担心该部分的实际实现细节被隐藏。他们所需要知道的关于你的函数和类的一切就是它们的接口。通过这种方式,您将同时拥有头文件和实现文件。
如果你把函数定义和它们的声明一起沿着放在头文件中,它们将是内联的,应该运行得更快,但是你的可执行文件会更大,每次都必须编译它们。实现细节也向用户公开。
如果你将函数定义放在头文件的相关代码文件中,它们将不会内联,你的代码将更小,运行可能会慢一点,但你只需要编译一次。实现细节是对用户隐藏和抽象的。

ar7v8xwq

ar7v8xwq3#

绝对没有理由把函数体放在'c'的头文件中。如果头文件包含在多个'c'文件中,这将迫使编译器多次定义函数。如果函数是静态的,程序中会有多个副本,如果是全局的,链接器会抱怨。
类似的推理也适用于c++。例外是类的“内联”成员和某些模板实现。
如果你在'cpp'文件中定义了一个临时类,在那里定义它并在类中定义函数体是完全可以的。

相关问题