Header Only Library
什么是Header Only Library
Header Only Library把一个库的内容完全写在头文件中,不带任何cpp文件. 这是一个巧合,决不是C++的原始设计.
第一次这么做估计是STL.在80年代末C++编译器还不支持模块分离(现在也不支持,以后估计也不会支持了), STL的作者不得不把模板的实现写在头文件中, 使得一个STL库的实现绝大部分都展示给了使用者.
第一次广泛被接受估计还是在Boost库,它不只提出使用hpp做为Header Only Library的文件后缀(因为这些头文件再也不能用于C语言了),还把一些原本不是Header Only的库变成了Header Only.
抛开一些外部约束不谈,Header Only Library有自己的优点:Header Only Library - Wikipedia benefits of header only libraries - stackoverflow
1.轻量级编译流程,集成编译非常简单,只需要指明所在路径,在C++实现文件中包含所需头文件即可.
2.编译器优化可以做得更好.因为内联函数和所有的实现都在编译时可见,所以可以进行相当多的优化,包括一些全局优化.
3.更好的代码设计.因为不能使用写全局变量和静态变量,以及所有的代码都公开可见,使得很多不良设计都无处藏身.
4.减少了ABI接口变更的风险.部分编译选项会导致静态库/动态库的ABI变化或者行为变化,库的作者需要提供多个版本的库文件, 包括但不限于32/64bit, 静态/动态库, struct layout等不同组合.
Header Only规避了这个问题.
当然它的缺点也很明显.
1.变更会导致全部组件重新编译.这就要求Header Only Library尽量应为相对稳定的功能库,而不是做为接口库.
2.代码组织不合理时,编译时间会显著变长.大量使用Header Only Library需要合量划分编译单元,减少编译单元的数量
可以有效提高编译速度.就我的实践来看每个编译单元应大于1万行(不包括头文件).boost separated source
Header Only Library常被误解会导致编译后代码变大. 因为Header Only Library大量使用模板技术, 以增加灵活性,
模板是会一定程度上增加编译结果的大小. 排除这一点, Header Only Library不会导致编译后代码明显变大.原因主
要是编译器的优化起作用.Benchmards - Stackoverflow
- 大量的内联会增加代码编译的结果.
- 按需实例化会减少不用的代码链接到代码中.
- 死代码发现机制,会减少一部分不使用的代码.
如何创建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可以在这里使用.
Header Only Library的更多相关文章
- 【转】Header Only Library的介绍
什么是Header Only Library Header Only Library把一个库的内容完全写在头文件中,不带任何cpp文件. 这是一个巧合,决不是C++的原始设计. 第一次这么做估计是ST ...
- Please ensure the argon2 header and library are installed
在CentOS上安装libargon2和libargon2-devel即可 yum install -y libargon2 libargon2-devel
- How to build the Robotics Library from source code on Windows
The Robotics Library is an open source C++ library for robot kinematics, motion planning and control ...
- c++中的header-only library
不同于在java中,虽然在java中,有些第三方库只是做了桥接的功能,比如slf4j-log4j-api,但是在运行时他们仍然是需要的,所以最多只能说是松耦合做得很好. 但是在c++中,一般我们应用第 ...
- Google C++ Style Guide
Background C++ is one of the main development languages used by many of Google's open-source project ...
- 关于c++风格 code style
Header files should be self-contained. All header files should have #define guards to prevent multip ...
- 安装coreseek找不到mysql
1.安装 coreseek-3.2.14 遇到问题:“ERROR: cannot find MySQL include files,随即在网上搜索各种答案说是要找到mysql.h的正确路径加入./co ...
- 升级openssl
升级openssl 依赖openssl的软件,如果是静态编译openssl,那么需要重新编译软件,如果是利用openssl的so动态库,那么只需要替换一下so文件并重启软件即可 openssh也依赖o ...
- mysql 升级方法
Performing an In-place Upgrade This section describes how to perform an in-place upgrade. Review Bef ...
随机推荐
- android签名生成和发布
首先,我们需要一个keystore,当然已经有了的话就不用这一步了:cmd下:进入到jdk的bin目录,这样的话,android.keystore文件就会生成在这个目录下,签名的时候我们需要这个文件C ...
- NOIP2005普及组第4题 循环
NOIP2005普及组第4题 循环 时间限制: 1 Sec 内存限制: 128 MB提交: 27 解决: 6[提交][状态][讨论版][命题人:外部导入] 题目描述 乐乐是一个聪明而又勤奋好学的孩 ...
- Py修行路 python基础 (十一)迭代器 与 生成器
一.什么是迭代? 迭代通俗的讲就是一个遍历重复的过程. 维基百科中 迭代(Iteration) 的一个通用概念是:重复某个过程的行为,这个过程中的每次重复称为一次迭代.具体对应到Python编程中就是 ...
- 什么是语义化的HTML
语义化的HTML使用每个html标签都特定的用途,例如p标签放大段文字, h1~h6常用于标题,strong加粗强掉….. 语义化的好处: 1:去掉或样式丢失的时候能让页面呈现清晰的结构: html本 ...
- Patator-一款很好用的爆破工具
项目地址:https://github.com/lanjelot/patator 打开文件夹 运行一下文件查看帮助 python patator.py --help 这里有很多的爆破选项,就不一一截图 ...
- List批量赋值的几种方法
List<int> list = new List<int>();list.AddRange(new int[] { 1, 5, 10, 20 ,33 }); //也可直接赋值 ...
- 取当前时间,格式为,yyyy-mm-dd hh:mm:ss
function CurentTime() { var now = new Date(); var year = now.getFullYear(); //年 var month = now.getM ...
- stm32中断 抢占优先级 和 响应优先级 有什么区别
与51不同,stm32的中断分类更灵活.51只是按先后顺序大小排列互相打断. stm32中多了响应优先级这一概念. stm32的中断分为 1.抢占(占先)优先级. 2.响应优先级. 1.抢占优先级.抢 ...
- [原创]Java使用反射及自定义注解实现对象差异性比较
Java项目C中 有一处逻辑,对于资源数据(类型为ResourceItem,拥有int/double/boolean/String类型数十个字段),需要比对资源数据每次变更的差异,并描述出变更情况.并 ...
- winform问题集锦
正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码 说明 .NET2.0中增加了42种非常强大的调试助手,MDA.Loaderlock 是其中之一.L ...