3DFDTD 软件C++编程规范

来源:互联网 发布:速卖通产品数据分析 编辑:程序博客网 时间:2024/05/01 16:22

          

 

 

C++编程规范

(技术管理)

                         

 

 

 

 

                     

               

                      起草人:卧浪居士

                      时间:2013.11.19



 

目录

1.    前言...3

2 管理内容...3

2.1 规范原则...3

2.2 命名的约定...3

2.3 排版的约定...4

2.4 注释的约定...5

2.5 可读性...6

2.6 函数的约定...6

2.7 类的约定...7

2.8 程序效率...7

3. 参考文献...8

 

1.      前言

计算机软件是一种知识密集的特殊产品,需要大量的人力和物力,生产难度大、成本高。如果忽视了编程的正确性、稳健性等质量属性,开发出来的软件便会隐含错误,其可读性等质量属性差,有的还会导致软件质量差和代码修改困难。因此,为提高软件的质量和可靠性,便于代码的交流、共享以及程序本身的调试和错误的排查,保证团队开发软件的一致风格,必须按照软件工程的规范和要求进行软件的开发。

根据目前普遍的看法,好的代码应该具有良好的稳定性、可靠性、可维护性和高的性能。按照这种标准,除去高性能一项,其他部分与程序员的编码风格有很大的关系。由此可见,遵守一定的编程规范,形成良好的编程风格,是多么重要。所谓编程规范,是指我们在编写程序代码时,应该遵守的一些原则,用以合理地使用编程语言的各种元素,发挥最好的编程效率。

编程规范注重于程序的物理结构和外观,而不是程序的逻辑结构。使用统一编码约定集合的主要原因,是使应用程序的结构和编码风格标准化,使之容易阅读、容易理解而且容易维护。

本规范目的是使现今正在开发的3DFDTD软件代码具有基本相同的风格,是软件保持比较好的规范性、可读性、可维护性、模块化、可移植性、可扩展性、可测试性等各种性能,特编写本规范。

本规范参照当前大公司所用的C++编程规范来编写,如Google、华为、中兴等,并未添加个人喜好。但为了保持现有软件源代码的一致性,在某些地方会与源代码保持一致性。



时间:2013.11.19

适用范围:3DFDTD软件以及PC端软件开发编程(C++)

2管理内容

2.1规范原则

     代码以结构清晰、简单易懂为主;一定的一致性、可维护性、可扩展性;

2.2命名的约定

最重要的一致性规则是命名管理,命名风格直接可以直接确定命名实体是:类型、变量、函数、常量、宏等等,无需查找实体声明,我们大脑中的模式匹配引擎依赖于这些命名规则。命名规则具有一定随意性,但相比按个人喜好命名,一致性更重要。

1.通用命名规则(General Naming Rules)

函数命名、变量命名、文件命名应具有描述性,不要过度缩写,类型和变量应该是名词,函数名可以用“命令性”动词。

2.文件名要全部小写

可以包含下划线(_),按项目约定来。通常,尽量让文件名更加明确,http_server_logs.h就比logs.h要好,定义类时文件名一般成对出现,如foo_bar.h和foo_bar.cc,对应类FooBar。

3. 类型命名(Type Names)

类型命名每个单词以大写字母开头,不包含下划线:MyExcitingClass、MyExcitingEnum。所有类型命名——类、结构体、类型定义(typedef)、枚举——使用相同约定。

4. 变量命名(Variable Names)

变量名一律小写,单词间以下划线相连,类的成员变量以下划线结尾,如m_Location,指针成员变量:m_pLocation。

5.全局变量(Global Names):

对全局变量没有特别要求,少用就好,可以以g_或其他易与局部变量区分的标志为前缀。

6. 函数命名(Function Names)

函数名以大写字母开头,每个单词首字母大写,没有下划线。

7. 命名空间(Namespace Names)

命名空间的名称是全小写的,其命名基于项目名称和目录结构:google_awesome_project。

8. 枚举命名(Enumerator Names)

枚举值应全部大写,单词间以下划线相连:MY_EXCITING_ENUM_VALUE。

9. 宏命名(Macro Names)(尽量用const或者是inline函数来取代宏)

如果使用,像这MY_MACRO_THAT_SCARES_SMALL_CHILDREN。

10. 命名规则例外(Exceptions to Naming Rules)

当命名与现有C/C++实体相似的对象时,可参考现有命名约定:

STL相似实体;参考STL命名约定;常量,类似INT_MAX

 

总结:目的就是使得变量名具有自说明性,从而使得代码可读性提高。并保持其在项目中的一致性。

2.3排版的约定

1. 程序块要采用缩进风格编写,缩进的空格数为4个。

2. 相对独立的程序块之间、变量说明之后必须加空行。

3.较长的语句(>80字符)要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。(可参见《Code Complete》 第二版)

4. 循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,长表达式要在低优先级操作符处划分新行,操作符放在上行之末。(为了保持与之前代码的一致性)

5.若函数或过程中的参数较长,则要进行适当的划分;(尽量输入参数在前,输出参数在后,并用const 来表明意图)。

6. 不允许把多个短语句写在一行中,即一行只写一条语句。

7.if、for、do、while、case、switch、default等语句自占一行,且if、for、do、while等语句的执行语句部分无论多少都要加括号{}。

8. 函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case语句下的情况处理语句也要遵从语句缩进要求。

9.程序块的分界符(如C/C++语言的大括号‘{’和‘}’)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。

应如下书写。

for (...)

{

    ... // program code

}

10.在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格。

说明:采用这种松散方式编写代码的目的是使代码更加清晰。

    总结:主要是为了可读性,一致性。

2.4注释的约定

说明:注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。并且具有一定的抽象性,参见《Code Complete》

1.一般情况下,源程序有效注释量必须在20%以上。

2. 说明性文件(如头文件.h文件等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。

3. 源文件头部应进行注释,列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等。

4.函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等。

5. 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。

6. 注释的内容要清楚、明了,含义准确,防止注释二义性。

7. 避免在注释中使用缩写。注释应与其描述的代码相近,对代码的注释应放在其上方。

8. 对于所有有物理含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须加以注释,说明其物理含义。变量、常量、宏的注释应放在其上方相邻位置或右方。

9. 数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,必须加以注释。

10. 全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明。

11. 注释与所描述内容进行同样的缩排。

12.将注释与其上面的代码用空行隔开。

13. 对变量的定义和分支语句(条件分支、循环语句等)最好编写注释,除了可以自说明。14.对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释。

说明:这样比较清楚程序编写者的意图,有效防止无故遗漏break语句。

15.避免在一行代码或表达式的中间插入注释。

说明:除非必要,不应在代码或表达中间插入注释,否则容易使代码可理解性变差。

16. 通过对函数或过程、变量、结构等正确的命名以及合理地组织代码的结构,使代码成为自注释的。

17. 在代码的功能、意图层次上进行注释,提供有用、额外的信息。

18. 注释应考虑程序易读及外观排版的因素,使用的语言若是中、英兼有的,建议多使用中文,除非能用非常流利准确的英文表达。

说明:注释语言不统一,影响程序易读性和外观排版,出于对维护人员的考虑,建议使用中文。

2.5可读性

1.注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。

2. 避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的枚举或const来代替。

3. 源程序中关系较为紧密的代码应尽可能相邻。

4. 不要使用难懂的技巧性很高的语句,除非很有必要时。

说明:高技巧语句不等于高效率的程序,实际上程序的效率关键在于算法。

2.6函数的约定

1. 对所调用函数的错误返回码要仔细、全面地处理。

2. 明确函数功能,精确(而不是近似)地实现函数设计。

3. 编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V操作)等手段对其加以保护。

4.由函数本身负责参数合法性检查。

5. 函数的规模尽量限制在200行以内。(若过分大于,则应考虑重构)

6.一个函数只应完成一个功能。(面向对象原则之一单一职责原则类似)

7. 为简单功能编写函数。

说明:虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。

8. 不要设计多用途面面俱到的函数。

说明:多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。

9. 函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的输出。

10. 避免设计多参数函数,不使用的参数从接口中去掉。

说明:目的减少函数间接口的复杂度。

11. 检查函数所有参数输入的有效性。

12. 防止把没有关联的语句放到一个函数中。

13. 只有当函数只有10行甚至更少时才会将其定义为内联函数(inline function)。

14. 非成员函数(Nonmember)、静态成员函数(Static Member)和全局函数(GlobalFunctions)

使用命名空间中的非成员函数或静态成员函数,尽量不要使用全局函数。

 

2.7类的约定

1. 不在构造函数中做太多逻辑相关的初始化;

2. 编译器提供的默认构造函数不会对变量进行初始化,如果定义了其他构造函数,编译器不再提供,需要编码者自行提供默认构造函数;

3. 为避免隐式转换,需将单参数构造函数声明为explicit;

4. 为避免拷贝构造函数、赋值操作的滥用和编译器自动生成,可目前声明其为private且无需实现;

5. 仅在作为数据集合时使用struct;

6. 组合>实现继承>接口继承>私有继承,子类重载的虚函数也要声明virtual关键字,虽然编译器允许不这样做;

7. 避免使用多重继承,使用时,除一个基类含有实现外,其他基类均为纯接口;

8. 接口类类名以Interface为后缀,除提供带实现的虚析构函数、静态成员函数外,其他均为纯虚函数,不定义非静态数据成员,不提供构造函数,提供的话,声明为protected;

9. 为降低复杂性,尽量不重载操作符,模板、标准类中使用时提供文档说明;

10. 存取函数一般内联在头文件中;

11. 声明次序:public->protected->private;

12. 函数体尽量短小、紧凑,功能单一。

13. 在非常特殊的情况下,例如对STL容器中对象,你应该只使用std::shared_ptr,任何情况下都不要使用auto_ptr。

14. 对于迭代器和其他模板对象使用前缀形式(++i)的自增、自减运算符。(这样做效率更高)

15. 强烈建议在任何可以使用的情况下都要使用const。

2.8程序效率

说明:代码效率分为全局效率、局部效率、时间效率及空间效率。全局效率是站在整个系统的角度上的系统效率;局部效率是站在模块或函数角度上的效率;时间效率是程序处理输入任务所需的时间长短;空间效率是程序所需内存空间,如机器代码空间大小、数据空间大小、栈空间大小等。

1.    编程时要经常注意代码的效率。

2.在保证软件系统的正确性、稳定性、可读性及可测性的前提下,提高代码效率。

3.局部效率应为全局效率服务,不能因为提高局部效率而对全局效率造成影响。

4. 循环体内工作量最小化。

5. 在保证程序质量的前提下,通过压缩代码量、去掉不必要代码以及减少不必要的局部和全局变量,来提高空间效率。

6. 在多重循环中,应将最忙的循环放在最内层。(代码局部性原理的使用)

7. 避免循环体内含判断语句,应将循环语句置于判断语句的代码块之中。

说明:目的是减少判断次数。循环体中的判断语句是否可以移到循环体外,要视程序的具体情况而言,一般情况,与循环变量无关的判断语句可以移到循环体外,而有关的则不可以。

8. 尽量用乘法或其它方法代替除法,特别是浮点运算中的除法。

 

 

3.参考文献

1. 华为公司编程规范和范例;

2. Google-C++编程规范;

3.深圳中兴集讯通信有限公司奇特标准(技术管理制度)

4.《Code Complete》第二版