谷歌C++编程规范
一、头文件
(1)注意保护头文件,防止头文件被多重包含,所有的头文件都必须使用#ifndef、#define和#endif进行保护,书写格式如下<PROJECT>_<PATH>_<FILE>_H_,全部使用大写。
例如:#ifndef FOO_H_,对应于foo.h头文件。
(2)在头文件中尽量少的包含别的头文件,如果可以请使用前置声明代替包含头文件。包含过多的头文件将会产生较强的依赖性,一旦文件有所改变,将会导致所有文件的重新编译。因此,尽量少的包含别的头文件而是用前置声明。
在头文件如何做到使用类Foo而无需访问类的定义?
1) 将数据成员类型声明为Foo *或Foo &;
2) 参数、迒回值类型为Foo的函数而是声明(但不定义实现);
3) 静态数据成员的类型可以被声明为Foo,因为静态数据成员的定义在类定义体外。
(3)在头文件中尽可能的不要包含内联函数,所有函数的定义(实现)必须写在源文件中。但是,若逻辑简单而且行数少于10行的函数可以写在头文件中,也可以写在-inl.h文件中,只要在使用的时候包含该头文件即可。
(4)函数参数的顺序:输入参数在前,输出参数在后(输入和输出)。输入参数使用值传递或者常数引用传递,输出参数使用非常数指针传递。
(5)包含头文件的顺序:项目头文件,系统头文件,标准库头文件。其中,头文件的命名全部使用小写,以较完整的路径作为文件名。
二、类和结构体
(1)构造函数:当没有构造函数的时候必须定义一个默认构造函数,不能使用编译器自动生成的默认构造函数,因为编译器生成的默认构造函数不会对非自定义类型成员进行初始化。
(2)将单参数的构造函数声明为explicit,防止不必要的隐式转换。
(3)当只有数据成员的时候,可以使用struct结构体
(4) 为避免拷贝构造函数、赋值操作的滥用和编译器自动生成,可目前声明其为private且无需实现;
(5) 组合>实现继承>接口继承>私有继承,子类重写的虚函数也要声明virtual关键字,虽然编译器允许不这样做;
(6) 避免使用多重继承,使用时,除一个基类有实现外,其他基类均为纯接口;
(7)接口类类名以Interface为后缀,除提供带实现的虚析构函数、静态成员函数外,其他均为纯虚函数,不定义非静态数据成员,不提供极造函数,提供的话,声明为protected;
(8) 为降低复杂性,尽量不重载操作符,模板、标准类中使用时提供文档说明;
(9)存取函数一般内联在头文件中;
(10) 声明次序:public->protected->private;(先函数后成员)最后是宏。
三、命名规则
1. 总体规则:不要随意缩写,如果说ChangeLocalValue写作ChgLocVal有情可原的话,把ModifyPlayerName写作MdfPlyNm就太过分了,除函数名可适当为动词外,其他命名尽量使用清晰易懂的名词;
2. 宏、枚举等使用全部大写+下划线;
3. 变量(类、结构体的成员变量)、文件、命名空间、存取函数(与成员变量相同)等使用全部小写+下划线,类成员变量以下划线结尾,全局变量以g_开头;
4. 普通函数、类型(类、结构体、枚举类型)、常量(k开头)等使用大小写混写,不用下划线。