C++ 是C/C+中的函数+;不可以吗?

C++ 是C/C+中的函数+;不可以吗?,c++,header,coding-style,project-structure,C++,Header,Coding Style,Project Structure,我正在编写一小段C/C++源代码。程序从stdin读取输入值,用算法处理它们,并将结果写入stdout 我只想在一个文件中实现所有这些,但我还需要算法的测试用例(不是输入/输出读取),因此我的项目中有以下文件: main.cpp sort.hpp sort_test.cpp 我立即在sort.hpp中实现了该算法,没有sort.cpp。它相当短,没有任何依赖关系 你会说,在某些情况下,头中定义的函数是可以的,即使它们是复杂的算法,而不仅仅是简单的访问器/变异器?或者我有什么理由避免这样做?什

我正在编写一小段C/C++源代码。程序从stdin读取输入值,用算法处理它们,并将结果写入stdout

我只想在一个文件中实现所有这些,但我还需要算法的测试用例(不是输入/输出读取),因此我的项目中有以下文件:

  • main.cpp
  • sort.hpp
  • sort_test.cpp
我立即在sort.hpp中实现了该算法,没有sort.cpp。它相当短,没有任何依赖关系


你会说,在某些情况下,头中定义的函数是可以的,即使它们是复杂的算法,而不仅仅是简单的访问器/变异器?或者我有什么理由避免这样做?什么时候我应该将代码从头文件移动到源文件?

可以在头文件中放置任何函数,只要它是内联的。在
类{}
和模板中定义的函数之类的东西是隐式
内联的

如果生成的应用程序太大,则优化代码大小。在出现问题之前进行优化是一种反模式,尤其是在“按您的方式”进行优化有好处的情况下,而且修复过程非常简单,只需从一个文件移动到另一个文件并删除
内联


当然,如果您想将代码作为库分发,那么在标头、静态库或动态库二进制文件之间做出决定是影响用户的一个重要决定。

这确实是一个艰难的选择。但是将它放在头中并不意味着它将是内联代码而不是函数。如果您想要相同的功能,可以使用inline关键字:

inline int max(int a, int b)
{
  return (a > b) ? a : b;
}

通常(对于非内联函数)应避免此操作的原因是,多个源文件将包含您的头文件,从而导致链接器错误。
无论您是否有pramga once或类似的技巧,如果有多个编译单元(例如cpp文件)包含相同的头,则会出现重复。

将函数放入头中时,必须确保将它们声明为
内联
。当多个.cpp文件包含该头文件时,这是避免重复定义警告所必需的。通常,您应该只在头文件中放置小函数,因为它将为每个包含头文件的cpp文件进行编译,这将减慢编译时间,并导致代码膨胀;较大的可执行文件

在头文件中包含函数并没有什么错,只要您理解折衷。将它们放入头文件意味着它们必须在包含头文件的任何翻译单元中编译(并重新编译)。(必须将它们声明为
内联
,否则将出现链接器错误。)

在具有许多翻译单元的项目中,如果您经常这样做,那么编译时间可能会明显减慢

另一方面,它确保函数定义在调用函数的任何地方都是可见的——这意味着它可以简单地内联,因此生成的程序可以运行得更快

最后,对于函数模板,您通常没有现实的选择。定义必须在调用站点可见,实现这一点的唯一实用方法是将其放在标题中

最后需要考虑的是,仅头部的库更易于部署和使用。你不需要链接任何东西,你不必担心ABI或其他任何东西。您只需将标题添加到项目中,包括它们,然后就可以开始了


相当多的流行库使用只头策略。

绝大多数库都是只头策略,所以我想说:是的,这是一种公认的做法。只要别忘了内联

如果你想内联函数,它必须在标题中,否则它无法内联

如果你用你的库发布了一个标题,并且标题中有某种实现,你可以肯定,几年后如果你改变了实现,并且它的工作方式与以前不完全一样,一些人的代码将被破坏,因为他们将依赖于他们在标题中看到的实现。是的,我知道一个人不应该这样做,但许多人确实会在标题中查找实现和其他行为,他们可以利用/使用非预期的方式来克服他们遇到的一些问题


若你们计划使用模板,那个么你们别无选择,只能把它全部放在标题中。(如果您的编译器支持导出模板,这可能不是必需的,但据我所知只有1个)。

可以在头中包含实现。这取决于你需要什么。如果您将定义分离到不同的文件,那么编译器将创建带有外部链接的符号,如果您不想在头本身内部定义函数的话。但是,您将为代码段浪费一些内存。如果将此头文件包含在两个不同的文件中,则两个文件代码段都将具有此函数定义


如果其他头文件将有一个具有类似名称的函数,那么这将是一个问题。然后您必须使用内联。

可能更适合。我认为任何比一行代码长的实现都应该在.cpp文件中。在.cpp文件中包含声明可能比在.hpp文件中包含实现要好一些@詹姆斯:什么,为什么?我不明白为什么它会更好地适合程序员。SEOF您的测试代码(<代码> SoTytTest.CPP ),您可以直接考虑包括<代码>排序。CPP < /代码>,这样您就可以测试它的内部函数。不用那么做,很好。它们只是自由函数,没有类,没有名称空间,什么都没有。但是,项目中只有一个cpp文件使用它。(程序的main.cpp,测试用例的sort_test.cpp)我猜我