在使用标准的头文件包含顺序可增强可读性,避免隐藏依赖。
#include的路径
项目内头文件应按照项目源代码目录树结构排列,避免使用UNIX特殊的快捷目录.
(当前目录)或..
(上级目录)。例如,project/src/base/logging.h
应该按照如下方式包含:
#include "base/logging.h"
#include的头文件包含顺序
如果dir/foo.c
的主要作用是实现或者测试dir2/foo2.h
的功能,foo.c
中包含头文件的次序如下:
* 1.dir2/foo2.h
(优先位置)
* 2.C系统文件
* 3.C++系统文件
* 4.其他库的.h
文件
* 5.本项目内的.h
文件
这种优先的顺序排序保证当dir2/foo2.h
遗漏某些必要的库时,dir/foo.c
的构件会立刻中止。因此这一条规则保证维护这些文件的人们首先看到构建中止的消息而不是维护其他包的人们。
如果依赖的符号被哪些头文件所定义,就应该包含哪些头文件,前置声明除外。比如要用到bar.h
中的某个符号,哪怕包含的foo.h
文件中已经包含了bar.h
,也照样包含bar.h
,除非foo.h
有明确说明它会自动提供bar.h
中的符号。
举例
progect/foo/internal/fooserver.c
的包含次序如下:
#include "foo/public/fooserver.h" //优先位置
#include <sys/types.h>
#include <unistd.h>
#include <hash_map>
#include <vector>
#include "base/basictypes.h"
#icnlude "base/commandlineflags"
#include "foo/public/bar.h"
以上是《Google C++ 编程风格指南》的观点,在《C++编程思想》则包含另一种观点。
《C++ 编程思想》认为头文件的包含顺序是从“最特殊到最一般”。
* 1.dir2/foo2.h
(接上例)
* 2.本项目内的.h
文件
* 3.其他库的.h
文件
* 4.C++系统文件
* 5.C系统文件
这是为了保证.h
文件的组成部分不被它自身解析。因为被自身解析缺乏明确提供的声明或者定义。
总结
《Google C++ 编程风格指南》和《C++ 编程思想》倡导的包含头文件的顺序各有优点,《Google C++ 编程风格指南》应该能大量减少隐藏的头文件依赖,而《C++编程思想》则很容易让你清楚知道你所定义的接口是否和系统库及第三方库发生冲突。
隐藏依赖:即一个头文件依赖其他文件。所以无论是《Google C++ 编程风格指南》还是《C++ 编程思想》都是将自身的头文件放在第一位,因为这样可以便于发现隐藏依赖。
- 参考《C++ 编程思想》、《Google C++ 编程风格指南》