C++编程规范:头文件
提倡
-
每一个.c文件(main.c除外)应有一个同名.h文件,用于声明需要对外公开的接口。
-
所有头文件都应当使用#define 防止头文件被多重包含,为了保证唯一性,更好的命名是PROJECTNAME_PATH_FILENAME_H。
**示例:**假定SYS工程的pwm模块的
pwm.h
,其目录为SYS/include/pwm/pwm.h
,可按如下方式保护:#ifndef SYS_INCLUDE_PWM_PWM_H #define SYS_INCLUDE_PWM_PWM_H ... #endif
头文件的版权声明部分以及头文件的整体注释部分(如阐述此头文件的开发背景、使用注意事项等)可以放在保护符(#ifndef XX_H)前面。
-
头文件中应放置对外部的声明,如对外提供的函数声明、宏定义、类型定义等。
-
头文件应当刚好自包含: 自包含就是任意一个头文件均可独立编译(不多不少)。
- 如果一个文件包含某个头文件,还要包含另外一个头文件才能工作的话,就会增加交流障碍,给这个头文件的用户增添不必要的负担。
- .c/.h文件禁止包含用不到的头文件
示例:
如果a.h不是自包含的,需要包含b.h才能编译。每个使用a.h头文件的.c文件,为了让引入的a.h的内容编译通过,都要包含额外的头文件b.h。额外的头文件b.h必须在a.h之前进行包含,这在包含顺序上产生了依赖。
-
头文件的包含关系是一种依赖。应当让不稳定的模块依赖稳定的模块,从而当不稳定的模块发生变化时,不会影响(编译)稳定的模块。
示例:
若a.c主要实现a.h中的内容,则a.c的头文件包含顺序应为(不同块的头文件应该用空行隔开):
- a.h
- C系统文件
- C++系统文件
- 其他库.h文件
- 本项目内的.h文件
**优点:**当a.h中遗漏某些必要的库时,a.c的构建会立刻终止,因此能够立刻对a.h进行维护。
-
头文件包含时可以使用源代码目录树结构排列,如
#include "src/pwm.h"
,增强可读性。
禁止
-
禁止在extern "C"中包含头文件。
示例:
头文件中引入extern "C"期望g++编译器以gcc的方式对某些函数进行编译(c++允许函数重载,其编译后生成汇编代码和C不同)。若在extern "C"中包含头文件,则可能造成extern "C"的循环嵌套、某些不期望以C方式编译的函数被处理。
-
禁止头文件循环依赖:a.h包含b.h,b.h包含c.h,c.h包含a.h,则三个文件任意一个改变时,另外两个都会重新编译;若a.h包含b.h,b.h包含c.h,则c.h改变时,仅有c.h和b.h被重新编译。