c++ 代码规范

http://tctop.wikispaces.com/Google%E4%BB%A3%E7%A0%81%E9%A3%8E%E6%A0%BC%E6%8C%87%E5%8D%97%E6%95%B4%E7%90%86


写代码时必须注重代码规范。养成良好的程序风格有助于提高代码的可维护性与可阅读性。 
Google推出了自己的《Google C++ 风格指南》,在这份指南中各种C++编程中遇到的风格问题都得到了规范。由于原版篇幅过长,我在这里整理一份简化版的编程规范,以供各位参考。同时希望每一位狂想曲创作组成员都能够用此代码规范编程。 
注意:此份资料仅仅是Google推荐的代码风格,不代表所有程序都要用此套规范编写,当然我们还是强烈建议在建立任何项目或是工程之前,都应该统一风格,以便日后维护。 
此套代码规范与常用的一些规范(如匈牙利命名法等)可能有所出入,如果您是第一次使用,也许会感到些许不适应,但还请多多习惯此种编码规范。 
另:本文档仅仅介绍的是C++编码风格指南,而并非编程规范或是编程优化指南,如若想了解更多的代码优化方法(如使用何种输入输出方式等)还请参考《effective C++》与《more effective C++》等著作。 
好了,下面开始我们正式的风格规范探索。 

一、头文件 
1. 头文件写在.h文件中,实现文件写在.cc中而不是写在.cpp中。 
2. 每个.cc文件都对应一个.h文件,包含main()函数的文件除外。 
3. 每个头文件都要用#define保护,格式:

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
…
#endif // FOO_BAR_BAZ_H_
4. 只有当函数少于10行时才建议使用内联函数,内联中包含循环或switch语句反而会降低效率。(Frankie注:不建议在内联函数中再调用其他函数) 
5. 复杂的内联函数与函数模板建议放在-inl.h文件中,并用#define保护。 
6. 函数参数顺序:先输入参数,然后输出参数。 
7. #include路径及顺序:该.cc的.h头文件、C库、C++库、其他库的.h文件、本项目内的.h文件。 

二、作用域 
1. 鼓励在.cc文件内使用匿名名字空间。不要在.h文件中使用匿名空间。 
2. 使用具名的名字空间时用名字把.h文件及.cc文件中除前置声明外的源文件全部封装起来。
// .h 文件
namespace mynamespace {
// 所有声明都置于命名空间中
// 注意不要使用缩进
class MyClass {
 public:
 …
 void Foo();
};
} // namespace mynamespace
// .cc 文件
namespace mynamespace {
// 函数定义都置于命名空间中
void MyClass::Foo() {
 …
}
} // namespace mynamespace
3. 最好不使用using namespace,而使用using ::foo::bar;类型。 
4. 尽量不使用裸的全局函数,而要使用静态成员函数或名字空间内的非成员函数。 
5. 尽可能将变量至于最小作用域内,尽可能用初始化方式替代声明再赋值,遇到for循环则要考虑效率问题(@July,代码大全,深入理解计算机系统都有阐述)。如:
// 低效的实现
for (int i = 0; i < 1000000; ++i) {
Foo f; // 构造函数和析构函数分别调用 1000000 次!
f.DoSomething(i);
}

// 高效的实现
Foo f; // 构造函数和析构函数只调用 1 次
for (int i = 0; i < 1000000; ++i) {
 f.DoSomething(i);
}
6. 禁止使用class类型的静态或全局变量,包括STL容器,尤其是在多线程中。 

三、类 
1. 构造函数只初始化那些没什么意义的(trivial)数据,有意义的(non-trivial)数据建议使用Init()函数。 
2. 如果类定义了若干成员变量且无其他构造函数,则需要定义一个默认构造函数。 
3. 仅当只有数据时使用struct,其他一概使用class。 

四、其他C++特性 
1. 输入参数是值参或const引用,输出参数为指针。输入参数可以为const指针,但决不能为非const的引用参数。 
2. 仅在输入参数类型不同但功能相同时使用重载函数,不要用函数重载去模拟缺省函数参数。 
3. 不允许使用缺省函数参数。 
4. 不使用异常。(Frankie注:我的理解是这是因为Google自身代码的健壮性造成的。Google认为使用异常并不能提高效率) 
5. 禁止使用RTTI。 
6. 使用C++类型转换,如static_cast<>()而不是不要使用 int y = (int)x或 int y = int(x) 等转换方式。 
7. 不要使用流而要使用printf()与scanf()(@July,尽量,但不盲从)。记录日志除外。 
8. 尽量使用前置自增自减,尤其是对迭代器和模板类型。 
9. 尽可能使用const。 
10. 使用断言来指出变量为非负数,而不是使用无符号整型。 
11. 整数用 0, 实数用 0.0, 指针用 NULL, 字符 (串) 用 '\0'。 
12. 尽可能用 sizeof(varname) 代替 sizeof(type)。 
13. 只是用Boost中被认可的库。 

五、命名规定 
1. 尽可能给出描述性的名称,如:int num_errors; int num_completed_connections;
2. 函数名通常是指令性的,如OpenFile(), set_num_errors()。 
3. 文件名要全部小写,可以包含下划线或连字符。(Frankie注:《狂想曲》统一使用下划线) 
4. 类型名称的每个单词首字母均大写且不含下划线:MyExcitingClass, MyExcitingEnum。 
5. 变量命名一律小写,单词之间以下划线连接。类成员变量以下划线结尾。如:
my_exciting_local_variable
my_exciting_member_variable_
6. 结构体变量的数据成员命名与普通变量一样。 
7. 常量命名在名称前加k:kDaysInAWeek。 
8. 常规函数每个单词首字母大写,没有下划线。 
9. get和set函数要与存取的变量名匹配。如:
class MyClass {
 public:
 ...
 int num_entries() const { return num_entries_; }
 void set_num_entries(int num_entries) { num_entries_ = num_entries; }
 
 private:
 int num_entries_;
};
10. 名字空间用小写字母命名,用下划线连接单词。 
11. 枚举的命名与常量或宏一致:kEnumName或ENUM_NAME,并且建议使用前者,即常量风格的命名方式。 
12. 宏命名全部大写,单词之间用下划线连接。(Frankie注:#define保护文件要用下划线结尾) 

六、注释(Frankie注:此处为本人根据实际结合Google代码规范提出的注释方法,适用于《狂想曲》)
1. 使用 
2. 在每个文件头加入版权公告,注明作者、修改日期、版本号等信息(只要是我们内部人员,就只标明作者)。
3. 函数或者变量等的注释没有太多要求,只需注意对齐,内容详尽即可。 
4. 对尚未完成或者需要改进的代码使用TODO注释。如:
// TODO(kl@gmail.com) Use a "*" here for concatenation operator.
// TODO(Zeke) change this to use relations.
TODO需要大写,括号内是您的名字,后接修改的方案等,是为了在“将来某一天做某事”,可以加上明确的时间或明确的事项。 

七、格式(Frankie注:格式内容涉及面较广,详细请参见Google代码风格指南源文档) 
1. 每行代码字符数不超过80。 
2. 用UTF-8编码。 
3. 只是用空格不适用制表位,每次缩进2个空格。 
4. 返回类型和函数名在同一行,参数尽量放在同一行。 
5. if, else, switch等语句一定要使用大括号{}。 

--------------------------------------------
尽量接近上面的标准,但不盲从,以下为个人自行补充:
八、
1、代码首要原则,保证可读性,然后是精准性,精简性。
2、变量名一定要规范,不要出现如select1,select2之类带数字的变量名称。
3、保证所有编写的代码都已经全面测试,反复测试,保证正确性。
4、尽量不使用全局变量。
5、尽量写成
if
{
}
而不是
if{

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值