Google C++ style guide——头文件

1.#define保护

使用#define防止头文件被多重包含。命名格式为:<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.头文件依赖

使用前置声明尽量减少.h文件中#include的数量。

头文件被更改时,需要重新编译。那些包含了该头文件的代码也需要重新编译,因此,我们应该实现尽可能少的在头文件中包含头文件。

前置声明可以明显的减少需要包含的头文件数量。假如你在一个头文件中需要用到类File,但不需要访问File的声明,则头文件只需前置声明class File。

在以下情况可以使用类Foo而无需访问类的定义。

1)将数据成员类型声明为Foo *或者Foo &;

2)参数、返回值类型为Foo的函数只是声明(不在头文件内定义实现);

3)静态数据成员的类型可以被声明为Foo(因为静态数据成员的定义在类定义之外)。

如果你的类是Foo的子类,或者含有类型为Foo的非静态数据成员,则必须为之包含头文件。

有时,使用指针成员替代对象成员的确更有意义。但是,这样的做法会降低代码可读性及执行效率。如果仅仅为了少包含头文件,还是不要替代比较好。

当然,.cc或者.cpp无论如何都需要所使用类的定义部分,自然也就会包含若干头文件。


3.内联函数

只有当函数只有10行甚至更少时才会将其定义为内联函数。

当函数被声明为内联函数之后,编译器可能会将其内联展开,无需按通常的函数调用机制调用内联函数。

优点:当函数体比较小的时候,内联该函数可以令目标代码更加高效。例如存取函数,以及其他一些比较短的关键执行函数。

缺点:滥用内联将导致程序变慢,内联有可能使目标代码量或增或建,这取决与被内联的函数的大小。内联较短小的存取函数通常会减少代码量,但内联一个很大的函数(如果编译器允许的话),将显著增加代码量。

在现在处理器上,由于更好的利用指令缓存,小巧的代码往往执行更快。

一个比较得当的处理规则是,不要内联超过10行的函数。对于析构函数应慎重对待,析构函数往往比其表面看起来要长,因为有一些隐式成员和基类析构函数(如果有的话)被调用。


虚函数和递归函数即使被声明为内联的,也不一定就是内联函数。通常,递归函数不应该被声明为内联的(递归调用堆栈的展开并不像循环那么简单,比如递归层数在编译时可能是未知的,大多数编译器都不支持内联递归函数)。析构函数内联的主要原因是其定义在类的定义中,为了方便抑或是对其行为给出文档。


4.-inl.h文件

复杂的内联函数的定义,应放在后缀名为-inl.h的头文件中。

在头文件中给出内联函数的定义,可令编译器将其在调用出内联展开。然后,实现代码应完全放到.cc文件中,我们不希望.h文件中出现太多实现代码,除非这样做在可读性和效率上有明显优势。

如果内联函数的定义比较短小、逻辑比较简单,其实现代码可以放在.h文件中。例如,存取函数的实现理所当然都放在类定义中。处于实现和调用的方便,较复杂的内联函数也可以放到.h文件中,如果你觉得这样会使头文件显得笨重,还可以将其分离到单独的-inl.h中。这样即把实现和类定义分离开来,当需要时包含实现所在的-inl.h即可。

同样的,-inl.h也是需要#define保护的。


5.函数参数顺序

定义函数事,参数顺序为:输入参数在前,输出参数在后。


6.将包含次序标准化可增强可读性、避免隐藏依赖,次序如下:C库、C++库、其他库的.h、项目内的.h。

相同目录下头文件按字母序是不错的选择。

Google C++ style guide——头文件

上一篇:atitit.spring3 mvc url配置最佳实践


下一篇:atitit.java给属性赋值方法总结and BeanUtils 1.6.1 .copyProperty的bug