有些团队所有成员写的代码都一致,10个人写的代码像1个人写的。正因为有代码规范,使得代码可读性强,方便代码review,利于后期维护。这体现了代码规范的重要性。接下来,在参考google的代码规范基础上,详细列举代码规范细节。
文件描述放在源文件或头文件顶部,包括:版权所有者、遵循协议、作者、功能介绍
// Copyright
// License
// Author
// Description
(1) 本类的头文件(放在首位,可减少依赖)
(2) C语言系统文件
(3) C++语言系统文件
(4) 其他库头文件
(5) 本项目其他头文件
(6) 系统头文件使用
(1) 源文件命名全部小写,以下划线连接:file_manager.cpp
(2) 头文件命名全部大写,以下划线连接:
#ifndef FILE_MANAGER_H_
#define FILE_MANAGER_H_
......
#endif // FILE_MANAGER_H_
类名首字母大写:class FileManager
接口命名以Interface结束
普通函数首字母大写:void Read(char* buf, int buf_size)
函数参数,全部小写,下划线连接
成员变量以下划线结尾:file_length_(也有存在以m开头的写法)
静态变量以s开头:sFileLength
全局变量以g开头:gFileLength
常量以k开头:kFileLength
变量、常量、函数命名需要详细,禁止数字、首字母缩写,尽量做到见名知意、详细命名。
命名空间全部小写
禁止使用using namespace xxx,避免污染命名空间
可以在源文件使用using,例如:using std::string
除了位运算,其他情况不使用无符号类型
模块内部定义exception,其他模块依赖后,无法捕获未知exception。
另外,不要在析构函数抛出异常,而是捕获所有异常并处理。
不要使用RTTI,单元测试可以使用
构造函数只进行赋值初始化,尽量不执行耗时操作或具体方法;
explicit修饰单参构造函数,避免隐式类型转换误用;
成员变量在构造函数进行初始化;
仅在需要拷贝构造对象时,使用拷贝构造函数;
否则在private内部调用DISALLOW_COPY_AND_ASSIGN宏,或者定义不可copy与assign基类。
class Uncopyable {
protected:
Uncopyable() {}
~Uncopyable() {}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
class Test : private Uncopyable {
......
};
尽量不要声明为全局变量,尽量不要把类成员变量暴露给外部访问。
函数尽量声明为private/protect,如果要声明public,也要避免被外部修改。
枚举名大写开头,枚举类型全部大写,下划线连接。
enum MediaType {
MEDIA_TYPE_VIDEO = 0,
MEDIA_TYPE_AUDIO,
MEDIA_TYPE_SUBTITLE
}
函数最外层左括号不换行,右括号换行(也有写法左括号换行)
函数体内部左括号不换行,右括号换行
void Function() {
if (condition) {
......
}
}
条件括号无空格,(condition)左右1个空格,if执行体为2或4空格缩进
if (condition) {
for (int i = 0; i < 10; i++) {
......
}
} else {
......
}
(1)如果要需要动态分配,哪里分配对象哪里保持它的所有权。
如果其他代码需要访问该对象,考虑传递其副本,或者传递指针或引用,而不是转移对象所有权。
(2)如果要共享对象,使用std::share_ptr
(3)尽量不要使用std::auto_ptr,而使用std::unique_ptr
使用显式类型转换,尽量不用c语言风格的强制类型转换
包括static_cast、const_cast、dynamic_cast、reinterpret_cast
使用sizeof(name),而不用sizeof(type)
HelloStruct hello;
memset(hello, 0, sizeof(hello));
使用inline内联函数,确保代码行数在10行内
不用修改的参数或函数,尽量使用const
bool IsRunning() const {
return running_;
}
(1)不要在.h头文件进行宏定义
(2)使用#define进行宏定义,用完后#undef
(3)尽量不用##来生成函数/类/变量名
每行代码尽量不要超过80字符
属于建议部分,函数参数或者判断条件对齐
构造函数参数:
FileManager::FileManager()
:name("test"),
mode("rw") {
......
}
成员函数参数:
FileManager::Read(char* buf,
long offset,
int buf_size) {
......
}
判断条件:
if (condition1 &&
condition2 &&
condition3) {
......
}
变量赋值,等号对齐(整齐美观,不强制要求):
int one = 1;
int two = 2;
int three = 3;
注释包括文件头注释、函数注释、结构体注释、接口注释、关键代码注释等。
代码注释使用 //,比如
// read buffer from stream
函数注释:
/**
* @brief Read buffer from stream
* @param buf a buf to cache data
* @param size how much data to read once a time
* @return 0 for success, < 0 for fail
*
**/
int Read(char* buf, int size) {
}
new和delete配对使用,原则上在哪里申请内存,在哪里释放(同一个对象里操作)。
创建数组使用new[],然后使用memset进行初始化,释放使用delete[]
尽量使用const或者enum代替define。
多态基类的析构函数声明为虚函数,避免无法调到派生类析构函数导致内存泄漏。
不要在构造函数或析构函数调用虚函数,内联函数、友元函数不要声明为虚函数。
参考文档:google版c++代码规范
参考书本: