只有标题 - 库的好处(Benefits of header-only libraries)

2019-06-18 09:33发布

什么是头的好处,只有库,为什么你会写这种方式反对把落实到单独的文件?

Answer 1:

有一些情况时,只有头库是唯一的选择,例如使用模板的时候。

有一个只有标题 - 库还意味着您不必担心其中可能使用的库不同的平台。 当你分开的实现,通常这样做隐藏实现细节,并分发库的头文件和库的组合( libdll的或.so文件)。 这些当然都被编译为您提供所有支持不同操作系统/版本。

您还可以分发的实施文件,但是这将意味着用户一个额外的步骤 - 在使用之前编译您的图书馆。

当然,这也适用于一个案件逐案的基础。 例如,仅标头的库有时增加 代码大小和 编译时间。



Answer 2:

只有头库的优点:

  • 简化构建过程。 你并不需要建立图书馆,而你并不需要在生成的链接步骤指定编译库。 如果你有一个编译库,你可能会想建立了多个版本:一是与调试编译启用,另一个与优化启用,并可能又剥离符号。 也许更对多平台系统。

一个只有标题库的缺点:

  • 更大的目标文件。 从库在一些源文件中使用的每个直线排列方式也将获得一个弱符号,乱线定义为源文件编译的对象文件英寸 这会减慢编译器,并减慢连接。 编译器生成所有的膨胀,然后链接器过滤出来。

  • 较长的编译。 除了上面提到的膨胀问题,因为头是比编译库中只有头库本身更大的编译将需要更长的时间。 那些大的标头将需要被解析为使用该库的每个源文件。 另一个因素是,在一个只有标题库的头文件必须#include由内置的定义,以及将有必要有图书馆已建成为一个编译库中的头文件所需的标题。

  • 更纠结的汇编。 你得到更多的依赖关系,因为这些额外的一个只有头库#include s的一个只有头库需要。 更改库中的一些关键功能的实现,你很可能需要重新编译整个项目。 使源文件中的这种变化已编译库,所有你需要做的就是重新编译一个库源文件,更新与新的.o文件编译的库,并重新链接应用程序。

  • 更难的人阅读。 即使有最好的文档,图书馆的用户经常不得不求助于读取头的图书馆。 在一个只有标题库的头都充满了实施细则的理解接口的方式获得。 随着编译库,所有你看到的是接口和实施做什么了简短的评论,而这通常是你想要的。 这真的是你应该想。 你不应该知道的实施细则,知道如何使用图书馆。



Answer 3:

我知道这是一个古老的线程,但没有人提到ABI接口或特定的编译器的问题。 所以,我想我会的。

这基本上是基于对你要么写一个库头分发到人或重用自己VS具有在头一切的概念。 如果你正在考虑在每一个项目中重用一个头文件和源文件并重新编译这些的那么这并不真正适用。

基本上,如果您编译C ++代码,并建立一个编译器库,然后用户尝试使用该库具有不同的编译器或不同的版本相同的编译器,那么你可能会由于二进制不兼容的链接错误或奇怪的运行时行为。

例如编译器厂商经常改变它们的实现版本之间的STL的。 如果您在接受一个std :: vector的库有一个函数,那么,预计该类字节被安排在当库编译它们排列的方式。 如果在新的编译器版本,供应商已取得的效率提高到std ::矢量则该用户的代码能够看到可具有不同的结构,并通过新的结构到媒体库中的新类。 一切顺利下坡从那里...这就是为什么我们建议不要越过界限库STL传递对象。 这同样适用于C运行时(CRT)类型。

在谈到CRT,在库和用户的源代码一般都需要对同CRT被链接。 使用Visual Studio,如果你建立一个使用多线程的CRT库中,而是针对多线程调试CRT用户的链接,那么你将有一个环节出现问题,因为你的库可能无法找到它所需要的符号。 我不记得哪个函数是,但为Visual Studio 2015年微软提出一个CRT函数内联。 突然有人在标头而不是CRT库,以便预计库在链接时发现它不再能做到这产生链接错误。 其结果是,这些库需要使用Visual Studio 2015年重新编译。

如果你使用Windows API您还可以得到链接错误或奇怪的行为,但你建立与不同的Unicode设置到库用户。 这是因为Windows API具有使用Unicode或ASCII字符串和宏/它自动地使用基于项目的统一设置的正确类型定义的功能。 如果您在图书馆界认为是错误的类型传递一个字符串,然后事情在运行时破裂。 或者,你可能会发现程序不会在第一时间联系起来。

这些东西也可用于跨库边界传递对象/类型从其他第三方库(例如,本征矢量或矩阵GSL)真。 如果第三方库改变了你编译你的库和用户编写自己的代码然后事情会打破他们之间的头。

基本上是安全的,你可以在图书馆界传递的唯一的东西是建立在类型与普通旧数据(POD)。 理想的情况是任何POD应该是在你自己的头文件中定义,不依赖于任何第三方的标头结构。

如果你只提供库头,那么所有的代码被用相同的编译器设置,并用同样头文件编译所以很多这些问题消失(提供的第三个版本部分库,你和你的用户使用的API兼容)。

但是有一些上面已经提及的底片,如增加编译时间。 你也可以运行一个企业,所以你可能不希望所有的手你的源代码实现的细节向所有用户的情况下,其中一人偷走。



Answer 4:

主要的“好处”是,它要求你提供源代码,所以你会在机器和你从来没有听说过的编译器错误报告而告终。 如果库完全模板,你没有太多的选择,但是当你有选择,只是头通常是一个贫穷的工程选择。 (在另一方面,当然,头只是意味着你没有记录任何整合的过程。)



文章来源: Benefits of header-only libraries