Google C++ 编码风格精简
头文件:
1.头文件防多重定义define格式:<PROJECT>_<PATH>_<FILE>_H_
2.能使用前置声明尽量不用头文件包含
3.只有当函数只有10行甚至更少时才将其定义为内联函数(注意虚函数,递归函数,以及使用了循环语句的函数)
4.复杂的内联函数的定义,放在后缀名为-inl.h的头文件中
5.定义函数时,输入参数永远放在输出参数之前
6.项目内头文件应按照项目源代码目录树结构排列
7.example.cc包含头文件顺序:example.h,C系统文件,C++系统文件,其他库的h文件,本项目内h文件
作用域:
1.在.cc文件中,允许甚至鼓励使用匿名名字空间;不要在h文件中使用匿名名字空间
2.在.cc文件.h文件的函数,方法或类中,可以使用"using"关键字及名字空间别名
3.不要将嵌套类定义成公有,除非它们是接口的一部分,比如,嵌套类含有某些方法的一组选项
4.使用静态成员函数或名字空间内的非成员函数,尽量不要用裸的全局函数
5.将函数变量尽可能置于最小作用域内,并在变量声明时进行初始化
6.禁止使用class类型的静态或全局变量:它们会导致很难发现的bug和不确定的构造和析构函数调用顺序
类:
1.构造函数中只进行那些没什么意义的初始化,可能的话,使用Init()方法集中初始化有意义的数据
2.如果一个类定义了若干成员变量又没有其它构造函数,必须定义一个默认构造函数
3.对单个参数的构造函数使用C++关键字explicit(如果构造函数只有一个参数,可看成是一种隐式转换)
4.仅在代码中需要拷贝一个类对象的时候使用拷贝构造函数;大部分情况下都不需要,此时应使用DISALLOW_COPY_AND_ASSIGN
{
#defineDISALLOW_COPY_AND_ASSIGN(TypeName)/
TypeName(constTypeName&);/
voidoperator=(constTypeName&)
}
5.仅当只有数据时使用struct,其它一概使用class
6.使用组合常常比使用继承更合理.如果使用继承的话,定义为public继承
7.如果你的类有虚函数,则析构函数也应该为虚函数
8.当重载一个虚函数,在衍生类中把它明确的声明为virtual
9.只在以下情况我们才允许多重继承:最多只有一个基类是非抽象类;其它基类都是以Interface为后缀的纯接口类
10.接口是指满足特定条件的类,这些类以Interface为后缀(不强制).
11.尽量不要重载运算符
12.数据成员在任何情况下都必须是私有的,并根据需要提供相应的存取函数
13.在类中使用特定的声明顺序:public:在private:之前,成员函数在数据成员前
14.如果函数超过40行,可以思索一下能不能在不影响程序结构的前提下对其进行分割
Google奇技:
1.尽量避免使用智能指针(任何情况下都不要使用auto_ptr),使用时也尽量局部化
2.使用cpplint.py检查风格错误
C++特性:
1.输入参数是值参或const引用,输出参数为指针.
2.仅在输入参数类型不同,功能相同时使用重载函数(含构造函数)
3.不允许使用缺省函数参数
4.不允许使用变长数组和alloca()
5.不要在Google的开源项目中使用异常(关于这一点google仅仅是为了自身方便=。=)
6.禁止使用RTTI
7.使用C++的类型转换,如static_cast<>().不要使用inty=(int)x或inty=int(x)等转换方式
{
用static_cast替代C风格的值转换,或某个类指针需要明确的向上转换为父类指针时
用const_cast去掉const限定符
用reinterpret_cast指针类型和整型或其它指针之间进行不安全的相互转换.仅在你对所做一切了然于心时使用dynamic_cast测试代码以外不要使用.除非是单元测试,如果你需要在运行时确定类型信息,说明有设计缺陷
}
8.只在记录日志时使用流
9.对迭代器和模板类型,使用前置自增(自减).对简单数值(非对象)无所谓
10.强烈建议你在任何可能的情况下都要使用const
{
如果函数不会修改传入的引用或指针类型参数,该参数应声明为const.
尽可能将函数声明为const.访问函数应该总是const.其他不会修改任何数据成员,未调用非const函数,不会返回数据成员非const指针或引用的函数也应该声明成const.
如果数据成员在对象构造之后不再发生变化,可将其定义为const.
}
11.C++内建整型中,仅使用int.如果程序中需要不同大小的变量,可以使用<stdint.h>中长度精确的整型,如int16_t
12.使用断言来指出变量为非负数,而不是使用无符号型
13.代码应该对64位和32位系统友好(!!!)
14.使用宏时要非常谨慎,尽量以内联函数,枚举和常量代替之
{
不要在.h文件中定义宏
在马上要使用时才进行#define,使用后要立即#undef
不要只是对已经存在的宏使用#undef,选择一个不会冲突的名称
不要试图使用展开后会导致C++构造不稳定的宏,不然也至少要附上文档说明其行为
}
15.整数用0,实数用0.0,指针用NULL,字符(串)用'/0'
16.尽可能用sizeof(varname)代替sizeof(type)
17.只使用Boost中被认可的库
命名约定:
1.函数命名,变量命名,文件命名应具备描述性;不要过度缩写.类型和变量应该是名词,函数名可以用“命令性”动词
2.文件名要全部小写,可以包含下划线(_)或连字符(-).按项目约定来.
3.类型名称的每个单词首字母均大写,不包含下划线:MyExcitingClass,MyExcitingEnum.
4.变量名一律小写,单词之间用下划线连接.类的成员变量以下划线结尾:my_local_variable,my_member_variable_
5.结构体的数据成员可以和普通变量一样,不用像类那样接下划线
6.常量命名在名称前加k,接大写字母开头的单词
7.函数名的每个单词首字母大写,没有下划线,取值和设值函数要与存取的变量名匹配.非常短小的内联函数名也可以用小写字母
8.名字空间用小写字母命名,并基于项目名称和目录结构:google_awesome_project.
9.枚举的命名应当和常量一致:kEnumName.
代码注释:
1.使用行注释或块注释,统一就好
2.在每一个文件开头加入版权公告,然后是文件内容描述
{
版权;
许可版本:Apache2.0BSDLGPLGPL;
作者;
文件内容
}
3.每个类的定义要附着类的功能和用法的注释
4.函数声明处注释描述函数功能,定义处描述函数实现
5.类数据成员应注释说明用途,是否可以接受NULL或-1等警戒值
6.全局变量注释说明含义和用途
7.复杂代码前要加注释;比较隐晦的代码后空两格加行尾注释
8.向函数传入整型,布尔值和指针时,注释说明含义,或使用常量让代码望文知意
9.临时,短期,或不够完美的解决方案使用TODO注释;格式//TODO(ID):Information
格式:
1.每一行长度不要超过80(路径,URL,头文件保护除外)
2.尽量不使用非ASCII字符,使用时必须使用UTF-8字符
3.只使用空格,每次缩进两个空格
4.函数声明:返回值和函数名在同一行,参数也尽量放在同一行
{
返回值总是和函数名在同一行;
左圆括号总是和函数名在同一行;
函数名和左圆括号间没有空格
圆括号与参数间没有空格;
左大括号总在最后一个参数同一行的末尾处;
右大括号总是单独位于函数最后一行;
右圆括号和左大括号间总是有一个空格;
函数声明和实现处的所有形参名称必须保持一致;
所有形参应尽可能对齐;
缺省缩进为2个空格;
换行后的参数保持4个空格的缩进;
}
5.如果函数声明成const,关键字const应与最后一个参数位于同一行
6.如果有些参数没有用到,在函数定义处将参数名注释起来
7.函数调用尽量放在同一行,否则,将实参封装在圆括号中
8.switch语句可以使用大括号分段.空循环体应使用{}或continue.
9.如果一个布尔表达式超过标准行宽断行方式要统一
10.return表达式中不要用圆括号包围
11.预处理指令不要缩进,从行首开始
12.访问控制块的声明依次序是public:,protected:,private:,每次缩进1个空格
13.构造函数初始化列表放在同一行或按四格缩进并排几行
14.名字空间内容不增加缩进层次
15.永远不要在行尾添加没意义的留白
16.不在万不得已,不要使用空行.尤其是:两个函数定义之间的空行不要超过2行,函数体首尾不要留空行,函数体中也不要随意添加空行
规则特例:
对于Windows程序员:
1.不要使用匈牙利命名法,使用Google命名约定,包括对源文件使用.cc扩展名
2.尽量使用原有的C++类型
3.使用MicrosoftVisualC++进行编译时,将警告级别设置为3或更高,并将所有warnings当作errors处理
4.不要使用#pragmaonce;而应该使用Google的头文件保护规则
5.除非万不得已,不要使用任何非标准的扩展,
结束语:
保持一致!
-------------参考:http://yangyubo.com/google-cpp-styleguide/index.html