Google C++编程规范(一)————(头文件篇)

开始在csdn上写一些文章了; 就拿《Google C++ Style Guide》开刀吧 :);本文不是完全一字一句对应翻译。而是本人边看边写个人理解。

 

头文件(Header Files)

  一般来说,.c/.cpp/.cxx 等文件都最好有一个.h文件;这样便于代码阅读和维护。当然可以例外,像一些只有一个main函数的小的源文件,就不需要额外增加头文件,如果增加,反而显得画蛇添足。

 

  头文件一般是用来给别的文件需要引用其中的变量或函数使用,google在这里从代码阅读和维护角度强调其重要性

#define防护

  #define一般用来防止重复包含导致编译时好重复编译。一般在头文件中这样使用,例如foo/src/bar/baz.h文件

    大概格式是<PROJECT>_<PATH>_<FILE>_H_

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_

...

#endif  // FOO_BAR_BAZ_H_

 

  搞这么复杂的原因是防止冲突:举个例子说:大家都喜欢用type.h或common.h,base.h 这些一目了然的名字谁都抢着用;

如果这个工程只有一个人写,还好说。这些名字自己想怎么用就怎么用。但是如果是一个庞大的工程,有几个人合作写。

结果程序员A写基础库的人用了base.h, 另外一个程序员B使用A写基础库,程序员B自己工程里面也有一个base.h;

如果大家都这样使用_BASE_H_,这样编译的时候就产生冲突了。所以最好加上前缀区分开。google使用的是用

工程+目录为前缀。不过本人习惯不是这样,使用目录一个不好的地方时,代码文件目录有时候经常重新规划,

从这个目录移到另一个目录,按照google这样定义,就要把代码文件翻出来,对宏一个个修改了。岂不是很麻烦

 

头文件依赖

 尽量最小化包含头文件关系,因为如果使用#include,头文件做一点修改,就会引起包含它的文件
重编译,这样会浪费大量工作时间。有一个避免的方法是使用前向申明;
 
#include "foo.h"
改成
class foo
并不是所有include地方都可以把#include改成前置申明。只有下面这些情况可以使用
1、成员变量使用指针或引用类型Foo* or Foo&. 而不是Foo;
2、函数参数或返回值使用Foo类型 或者 构造函数的参数是隐式转化的时候
3、使用Foo类型的变量是静态变量。

另 一方面,如果你的类继承自Foo或者你有一个类数据成员是Foo,那就必须包含Foo的头文件。
有些时候,使用指针(scoped_ptr 更佳)成员而不是对象成员(object member)是明智的。然而这却降低了代码的可读性,并且导致性能损失。、
所以,如果这么做的目的只是减少头文件中的#include,那就别这么做。当然,.cpp文件必须需要它所使用的类的定义,所以它会#include比较
多的头文件
为什么有的地方需要使用前置申明,有的地方不能使用呢?归根到底是要看使用的地方在编译的时候是否需要了解Foo类的内部结构,如一个成员
变量 Foo member;编译的时候,需要计算该变量占用的内存大小,这样必须要知道Foo类的内部细节,必须使用#include,而当变量是
Foo * member时候;编译的时候编译器知道不管Foo如果变化,此指针始终占用4个直接,可以不用了解Foo类的内部细节,直接分配计算变量
占用空间。

内联函数
 内联函数用来定义一些小函数,一般小于10代码的函数,适合使用内联函数,内联函数编译时直接在调用的地方展开,没有函数
出栈入栈的开销,所以不使用内联的时候要高效一点。但是由于是直接展开,违背了代码重用的原则,导致代码空间膨胀。
 其实内联函数就是一种用空间换取时间的做法。
 几个地方最好不要使用内联函数
 1、析构函数,析构函数往往比看起来大很多,因为它们会隐式的调用成员或者基类的析构函 数。另外析构函数往往是虚函数。
 2、switch和循环的函数
 3、虚函数和递归函数

inl.h文件

当你需要使用复杂的内联函数时,你可以使用文件名 后缀为-inl.h的文件来定义它。
内联函数的定义要放在头文件里,这样编译器在函数调用点才能访问到定义用于内联。然而,函数的实现代码通常放在.cc中,而且我 们也不喜欢把太多的实际代码放在.h文件中,除非这么做有利于可读性或性能。
如果一个内联函数的定义很短, 里面几乎没有任何逻辑,你应该把这样的定义代码放到.h文件中

函数参数顺序

定义函数参数的顺序:先输入参数,再输出参数。

将纯输入参数放在任何输出参数之前。尤其不要因为一个参数是新添加的,就把它放在函数参数的最后,要将纯输入参数 放在输出参数之前。
这不是个硬性规则。那种既是输入又是输出的参数。自己取舍吧:)

文件包含的名字和顺序

 使用标准顺序以保证可读性,并且避免隐藏的依赖:C库,C++库,其他库的.h,你的项目的.h。

所有项目的头文件应作为项目源文件目录的后代列出,不要使用UNIX中的目录快捷方式 . (当前目录)和 .. (父目录)。

举个例子,google-awesome-project/src/base/logging.h应该以#include “base/logging.h”的格式包含。

在每个部分(section)中,根据字母顺序排列是不错的方式。

 

举个例子,google-awesome-project/src/foo/internal/fooserver.cc中 的文件包含顺 序可能是这样:

#include "foo/public/fooserver.h"  // Preferred location.

#include <sys/types.h>
#include <unistd.h>

#include <hash_map>
#include <vector>

#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/public/bar.h"

顺序规则

  1. foo/public/fooserver.h (preferred location — 保证该头文件能独立编译,所以放在首要位置).
  2. C system files.
  3. C++ system files.
  4. Other libraries' .h files.
  5. Your project's .h files.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值