首页 > 代码库 > 对Google C++编程规范的理解和实践

对Google C++编程规范的理解和实践

1. #define保护 
所有头文件都应该使用#define 防止头文件被多重包含(multiple  inclusion),命名格式为:

<PROJECT>_<PATH>_<FILE>_H_ 

为保证唯一性,头文件的命名应基于其所在项目源代码树的全路径。例如,项目foo 中的头文件

foo/src/bar/baz.h按如下方式保护: 
#ifndef FOO_BAR_BAZ_H_ 
#define FOO_BAR_BAZ_H_ 
... 

#endif // FOO_BAR_BAZ_H_ 

这个规则能帮我们解决很多麻烦,坚持应用此规则应该是比较好的编程风格,尤其是在中大型项目中,头文件太多,重复包含的可能就会很高。

2. 头文件依赖 
使用前置声明(forward declarations)尽量减少.h 文件中#include的数量。 当一个头文件被包含的同时也引入了一项新的依赖(dependency),只要该头文件被修改,代码就要重新编译。如果你的头文件包含了其他头文件,这些头文件的任何改变也将导致那些包含了你的头文件的代码重新编译。因此,我们应该尽量少的包含头文件,尤其是那些包含在其他头文件中的。 
 使用前置声明可以显著减少需要包含的头文件数量。举例说明:头文件中用到类File,但不需要访问File的声明,则头文件中只需前置声明class File;无需#include "file/base/file.h"。 
 在头文件如何做到使用类Foo而无需访问类的定义? 
1) 将数据成员类型声明为Foo *或Foo &; 
2) 参数、返回值类型为Foo的函数只是声明(但不定义实现); 
3) 静态数据成员的类型可以被声明为Foo,因为静态数据成员的定义在类定义之外。 
另一方面,如果你的类是Foo的子类,或者含有类型为Foo的非静态数据成员,则必须为之包含头文件。 有时,使用指针成员(pointer members,如果是scoped_ptr更好)替代对象成员(object members)的确更有意义。然而,这样的做法会降低代码可读性及执行效率。如果仅仅为了少包含头文件,还是不要
这样替代的好。  当然,.cc 文件无论如何都需要所使用类的定义部分,自然也就会包含若干头文件。 

注:能依赖声明的就丌要依赖定义。 

这条规则的作用远超我们以为它能带来的作用(至少在我自己的经历中是这样的)。在一个中型项目中,头文件包含来包含去,很有可能就会形成一个环。举例来说A.h包含了B.h,B.h包含了C.h,而C.h又包含了A.h。这就形成了一个环。这种循环包含的编译错误往往莫名其妙,比如就我遇到的是(环境为windows xp+VS2005):fatal error C1189: #error :  FD_SETSIZE must be defined to 1024。错误的提示是FD_SETSIZE必须被定义为1024.一般头文件中用到的情况如上面所示,就直接用前置声明就好,不需要包含把头文件包含进来,既容易引起循环包含,还会引入新的依赖。

综上,Google 的C++编程规范确实是非常好的建议,值得仔细研究和实践。



 

对Google C++编程规范的理解和实践