博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转】Header Only Library的介绍
阅读量:4580 次
发布时间:2019-06-09

本文共 2006 字,大约阅读时间需要 6 分钟。

Header Only Library把一个库的内容完全写在头文件中,不带任何cpp文件. 这是一个巧合,决不是C++的原始设计.

第一次这么做估计是STL.在80年代末C++编译器还不支持模块分离(现在也不支持,以后估计也不会支持了), STL的作者不得不把模板的实现写在头文件中, 使得一个STL库的实现绝大部分都展示给了使用者.

第一次广泛被接受估计还是在Boost库,它不只提出使用hpp做为Header Only Library的文件后缀(因为这些头文件再也不能用于C语言了),还把一些原本不是Header Only的库变成了Header Only.

抛开一些外部约束不谈,Header Only Library有自己的优点: 

1.轻量级编译流程,集成编译非常简单,只需要指明所在路径,在C++实现文件中包含所需头文件即可.

2.编译器优化可以做得更好.因为内联函数和所有的实现都在编译时可见,所以可以进行相当多的优化,包括一些全局优化.
3.更好的代码设计.因为不能使用写全局变量和静态变量,以及所有的代码都公开可见,使得很多不良设计都无处藏身.
4.减少了ABI接口变更的风险.部分编译选项会导致静态库/动态库的ABI变化或者行为变化,库的作者需要提供多个版本的库文件, 包括但不限于32/64bit, 静态/动态库, struct layout等不同组合.
Header Only规避了这个问题.

当然它的缺点也很明显.

1.变更会导致全部组件重新编译.这就要求Header Only Library尽量应为相对稳定的功能库,而不是做为接口库.

2.代码组织不合理时,编译时间会显著变长.大量使用Header Only Library需要合量划分编译单元,减少编译单元的数量
可以有效提高编译速度.就我的实践来看每个编译单元应大于1万行(不包括头文件).

Header Only Library常被误解会导致编译后代码变大. 因为Header Only Library大量使用模板技术, 以增加灵活性,

模板是会一定程度上增加编译结果的大小. 排除这一点, Header Only Library不会导致编译后代码明显变大.原因主
要是编译器的优化起作用.

  1. 大量的内联会增加代码编译的结果.
  2. 按需实例化会减少不用的代码链接到代码中.
  3. 死代码发现机制,会减少一部分不使用的代码.

如何创建Header Only Library

首先应选一个名字空间,比如 work4me,建议使用全小写,最好与web domain相同. 头文件中所有类,常量,函数,模板,枚举以及联合

都应在这个名字空间之内声明. 头文件也应放在同名目录之内, 且使用hpp做为后缀.

头文件中除了命名空间以外,只能包括:

  • 类/枚举/联合的声明和定义
  • 常量/常量表达式的声明和定义
  • 类模板,函数模板定义
  • typedef和using产生的名字.
  • 内联函数和内联成员函数的定义

建议提供一个fwd.hpp来放置所有模板的前置声明, 以及一些函数和函数模板的前置声明. 因为如果在模板声明中用到默认参数,用户就没有

办法写自己的模板前置声明.(默认模板参数只能在第一次声明时指定,且只能指定一次,那怕各处都保持一致也会编译失败).

特别需要注意所有函数定义,都需要加上inline关键字.

不能使用static定义任何全局的变量和函数.不能定义类的static变量成员,但可以定义内联的static成员函数.

不能使用匿名命名空间.如果需要向用户隐藏一些接口或类型,可以使用details/impl等表示实现的嵌套命名空间.

如果依赖标准库以外的第三方库,应在ReadMe中做出说明.

如果依赖平台库比如windows.h/pthread.h等平台专有库,可以考虑bridge模式把这实现部分放到win32,linux等嵌套命名空间下.

什么时候适用

Header Only Library适合通用类库,因为需求变动不大,对灵活性和效率要求较高.包括boost内这些语言工具,基础算法,基础工具.

不适合功能性比较强,需要减少耦合的地方.比如一些正交的功能模块.

做为折中,可以把功能模块本身写成Header Only Library,但使用一个编译单元把它与其它部分隔离.常用的隔离技术比如PIMPL可以在这里使用.

 

==============================================

本文转载于http://www.cnblogs.com/ahuangliang/p/cxx-practices-header-only-library.html

作者黄亮

转载于:https://www.cnblogs.com/beimingke/p/7118817.html

你可能感兴趣的文章
Extjs4:改变Grid单元格背景色(转载)
查看>>
【翻译】go memory model
查看>>
深入学习webpack(一)
查看>>
mac 配置nginx 虚拟域名(转载)
查看>>
Xshell6设置字体大小
查看>>
软件开发模式
查看>>
Java总结篇系列:Java多线程(三)
查看>>
【项目管理】PM如何给组员分配任务(转载)
查看>>
Spring中的applicationContext文件详解
查看>>
Zookeeper安装和部署
查看>>
201621123042《java程序设计》第十三次作业
查看>>
CAST 和 CONVERT
查看>>
tr:even 与tr:odd
查看>>
Visual Studio2008 代码度量
查看>>
sql CONVERT函数应用
查看>>
洛谷 P3927 Factorial
查看>>
Wince 6.0获取设备的分辨率 自动设置窗体位置
查看>>
git
查看>>
[转帖]一文读懂 HTTP/2
查看>>
sql游标模板
查看>>