C / C ++标头中的函数是否可以通过?

| 我正在处理非常小的C / C ++源代码。该程序从stdin读取输入值,使用算法对其进行处理,然后将结果写入stdout。 我只需要在一个文件中实现所有这些功能,但是我还想要算法的测试用例(而不是输入/输出读数),因此我的项目中有以下文件: main.cpp sort.hpp sort_test.cpp 我马上在sort.hpp中实现了算法,没有sort.cpp。它很短,没有任何依赖性。 您是否会说,即使在某些情况下,标头中定义的函数也可以,即使它们是复杂的算法,而不仅仅是简单的访问器/更改器?还是有原因我应该避免这种情况?什么时候应该将代码从标头移到源文件?     
已邀请:
绝大多数的Boost库都是仅标头的,所以我会说:是的,这是一种既定并被接受的做法。只是不要忘记to0ѭ。     
只要您了解权衡,在头文件中具有功能就没有错。将它们放在头文件中意味着它们将必须在任何包含头的翻译单元中进行编译(并重新编译)。 (并且必须将它们声明为“ 0”,否则您将得到链接器错误。) 在很多翻译单元的项目中,如果您经常这样做,则编译时间可能会明显下降。 另一方面,它确保函数定义在调用函数的任何地方都可见-这意味着可以对其进行内联,因此生成的程序可能运行得更快。 最后,使用功能模板,通常没有现实的选择。该定义必须在调用站点上可见,并且实现该定义的唯一实用方法是将其放在标头中。 最后要考虑的是,仅标头的库更易于部署和使用。您不需要链接任何东西,也不必担心ABI或其他任何东西。您只需将标题添加到您的项目中,包括它们就可以了。 少数流行的库使用仅标头策略。     
将函数放在标头中时,必须确保将其声明为“ 0”。当多个.cpp文件包含该头文件时,需要这样做以避免重复定义警告。通常,您只应在标头文件中放入小函数,因为它将为包含标头的每个cpp文件进行编译,这会减慢编译时间并导致代码膨胀;较大的可执行文件。     
可以将任何函数放在标头中,只要它为“ 0”即可。诸如在
class { }
中定义的函数和模板之类的事物暗含在
inline
中。 如果生成的应用程序太大,则优化代码大小。在出现问题之前进行优化是一种反模式,尤其是当按照“您的方式”进行操作时,它的好处很简单,即从一个文件移至另一个文件并清除“ 0”很简单。 当然,如果要以库形式分发代码,则在标头,静态库或动态库二进制文件之间做出决定是影响用户的重要决定。     
那确实是一个明智的选择。但是,将其放在标头中确实意味着它将是内联代码而不是函数。如果您想要相同的功能,则可以使用inline关键字:
inline int max(int a, int b)
{
  return (a > b) ? a : b;
}
http://en.wikipedia.org/wiki/Inline_function     
通常(对于非内联函数)应避免这种情况的原因是,多个源文件将包含您的标头,从而导致链接器错误。 拥有一次普拉格舞或类似技巧并不重要-如果您有多个包含相同标头的编译单元(例如cpp文件),则会显示重复项。     
如果要内联函数,则该函数必须位于标题中,否则无法内联。 如果您发布带有库的标头,并且标头中包含某种实现,则可以确保,如果几年后更改实现,它的工作方式将与以前完全不同,人们代码将中断,因为它们将依赖于头文件中看到的实现。是的,我知道一个人不应该这样做,但是许多人确实在头文件中查找实现和其他行为,他们可以以一种非预期的方式利用/使用它们来克服他们遇到的一些问题。 如果您打算使用模板,则别无选择,只能将其全部放在标题中。 (如果您的编译器支持导出模板,但我只知道1个,则可能没有必要)。     
可以在标头中包含实现。这取决于您的需求。如果将定义分隔到另一个文件,则编译器将创建具有外部链接的符号,如果您不希望可以在标头本身中定义函数。但是您会在代码段上浪费一些内存。如果将此头文件包含在两个不同的文件中,则两个文件代码段都将具有此功能定义。 如果其他头文件将具有名称相似的函数,那么它将成为问题。然后,您必须使用内联。     

要回复问题请先登录注册