不同点,我猜。
- 二进制大小。仅标头会给客户端带来大小负担吗?
- 编译时间。仅标头是否意味着编译性能显着下降?
- 运行时性能。仅标头能否提供卓越的性能?
- 限制。设计是否只需要标题?
关于二进制大小。
还有一点安全感
如果 boost 库中有很多可访问的代码,或者编译器无法争论客户端是否可以访问的代码,则必须将其放入最终的二进制文件中。 (*)
在具有包管理(例如基于 RPM 或 .deb)的操作系统上,共享库可能意味着二进制分发大小的大幅减少并具有安全优势:安全修复程序分发得更快,然后被所有人自动使用.so/.DLL 用户。所以你有一个重新编译和一个重新分发,但是 N 个奸商。使用仅标头库,您有 N 次重新编译,N 次重新分发,总是针对每个修复程序,并且这些 N 中的一些成员在自己已经。
(*) 此处可到达的意思是“可能执行”
关于编译时间。
一些 boost 库非常庞大。如果你想#include 全部,每次你在源文件中更改一点,你都必须重新编译你#included 的所有内容。
这可以用樱桃采摘的标头来反制,例如
#include <boost/huge-boost-library.hpp> // < BAD
#include <boost/huge-boost-library/just-a-part-of-it.hpp> // < BETTER
但有时您真正需要包含的内容已经大到足以削弱您的重新编译。
对策是使其成为静态或共享库,反过来意味着“完全编译一次(直到下一次 boost 更新)”。
关于运行时性能。
我们还没有到一个全局优化可以解决我们所有的 C++ 性能问题的时代。为确保为编译器提供所需的所有信息,您可以只制作头文件并让编译器做出内联决策。
在这方面,请注意,由于 CPU 上的缓存和推测问题,内联并不总是能提供卓越的性能。
还请注意,此参数主要与可能经常使用的 boost 库有关,例如可以预期boost::shared_ptr<> 会被非常频繁地使用,因此是一个相关的性能因素。
但请考虑真正且唯一相关的原因 boost::shared_ptr<> 仅是标头 ...
关于限制。
C++ 中的某些东西不能放入库中,即模板和枚举。
但请注意,这只是对了一半。您可以为您的真实数据结构和算法编写类型安全的模板化接口,而这些接口又在库中具有它们的运行时通用实现。
同样,C++ 中的一些内容应该放入源文件中,如果是 boost,则应该放入库中。基本上,这就是所有会给出“多重定义”错误的东西,比如static 成员变量或一般的全局变量。
一些例子也可以在标准库中找到:std::cout在标准中定义为extern ostream cout;,所以cout基本上需要something(库或源文件)的分发定义它一次且仅一次。