至于Native C,我确实注意到它们在GCC中已经完成(当然,在Windows的Visual Studio中为头文件)。
那么这只是一种惯例吗?还是有原因呢?
将函数主体放入.cpp
文件中可以实现以下目的:
让编译器只解析和编译它们一次,而不是强制在包含头文件的每个地方都重新编译它们。此外,在头文件实现的情况下,链接器稍后还必须检测并消除到达不同对象文件的相同外部链接函数。
由许多现代编译器实现的头文件预编译工具可能会显着减少重复重新编译相同头文件所需的浪费努力,但它们并不能完全消除这个问题。
将这些函数的实现隐藏起来,不让模块或库的未来用户看到。实现隐藏技术有助于强制执行某些编程原则,从而减少模块之间的寄生性互相依赖,从而导致更清晰的代码和更快的编译时间。
我甚至认为即使用户可以访问库的完整源代码(也就是说,他们对其没有真正的“隐藏”),通过头文件显示出来的内容和不应显示的内容之间的清晰分离有益于库的自我文档化属性(尽管这样的分离也可以在仅包含头文件的库中实现)。
使一些函数对外部世界“不可见”(即具有内部链接性质,在类方法的示例中不是立即相关的)。
驻留在特定翻译单元中的非内联函数可以受到某些上下文相关的优化。例如,两个具有相同尾部部分的不同函数最终可能会“共享”实现这些相同尾部的机器代码。
在头文件中声明为内联的函数将在不同的翻译单元(即在不同的上下文中)中多次编译,并且稍后必须由链接器消除,这使得更难(如果可能的话)利用此类优化机会。
其他我可能错过的原因。
:)
- undefined这是一种约定,但也取决于具体的需求。例如,如果您正在编写一个库,希望功能快速(内联),并且设计此库供他人使用为一个简单的“header only”库,则可以在头文件中编写所有代码。
另一方面,如果您正在编写将链接静态或动态库的库,并且您正在尝试从用户封装内部对象数据,则编写函数 - 类成员函数等方式为它们应该执行的操作,使得您的库代码的用户不必担心其实际实现细节,只需要知道函数和类的接口即可。这样,您将同时拥有头文件和实现文件。
如果您将函数定义与其声明放置在头文件中,则它们将被内联,并且应该运行更快,但您的可执行文件会更大,并且每次都必须重新编译。实现细节也对用户暴露出来。
如果您将函数定义放置在相关代码文件中,则它们将不会内联,您的代码将更小,可能运行略慢,但您只需要编译一次。实现细节被隐藏并抽象化了。
.cpp
文件和你的main()
函数,必须直接或间接地包含整个代码。这对于小程序可能有效,但要用这种方式编译Linux内核,好运。 - Sam Varshavchik