编程规范要求

来源:互联网 发布:莳绘钢笔淘宝 编辑:程序博客网 时间:2024/04/30 10:45
 

1:

编写功能模块前必须提交模块设计说明。

其中要求包括设计的动态流程图,静态UML图,状态图,数据流图,线程交互图,数据库设计,设计模式,模块交互图,限制条件,生命周期,安全性设计,效率优化设计,相关策划案,对其他模块或第三方库的依赖关系,提供的核心接口函数,预计开发周期。

若上述模块没有涉及的,可留空。

 

2:

头文件必须以.h或.hpp(除编辑器生成外,不允许.hpp文件)为文件后缀。

inline文件可以以.inl为后缀。

template文件可以以.tem为后缀。

脚本文件以相应的后缀使用,例如.lua,  .python,  .us, .as等

纯C程序定义文件使用.c 为后缀。

C++程序定义文件使用.cpp为后缀。特殊情况允许使用.cc和.cxx为后缀。

 

3:

头文件以及源文件内必须有版权和版本信息。要求如下:

/*

* Copyright (c) 2010, 北京XX公司 All rights reserved.

* 文件名称:filename.h

* 简要说明:本文件的作用

* 当前版本:V3.0

* 作者:FreeKnight

* 日期:2010-12-20

*

* 修改者:FreeKnight

* 修改日期:2010-12-21

* 修改内容: 增加删减或修改的内容

* 修改时版本:V3.1

*/

 

4:

头文件规则:

1> VC7.1版本以上可使用#program once,以下必须使用#ifdef #define ... #endif 包括预处理块。

2> 先使用#include <file.h> 格式引用标准库头文件。

3> 再使用#include "file.h" 格式引用非标准库头文件。

4> 引擎部的对外公开头文件,内部私有头文件,源文件必须分别存储三个目录内,便于发布。

头文件建议:

1> 不要在头文件内存放“定义”。

2> 避免在头文件使用全局变量。

3> 头文件内可以使用类,函数声明的,避免直接包含其他头文件。

4> 避免预编译头庞大,仅存放常用头即可。

5> 若是库代码,对外暴露的头文件和对内的预编译头文件建议区分开来。

6> 除非关联性极强的类和结构,建议单一类单一头文件,不要一个头文件内定义大量的类。

 

5:

源文件内每个函数定义结束后都要加空行。

一个函数内,逻辑密切的语句间不加空行,但逻辑不密切的语句间应加空行分割。

一行代码应当只做一件事情,以便添加注释。

if, for, while, do 等语句应当自占一行,执行语句不得紧跟其后。无论执行语句多短,都必须添加大括号,大括号各占一行。

对于&&,||进行操作时,每个分支应当以括号包含起来。

复杂的长表达式,也应当根据优先级使用括号包含起来。

代码行最大长度建议控制在60个字符以内,若超过,建议换行。换行时,建议操作符放在新行首部。

避免使用多用途的符合表达式。例如 if( d = ( a = b + c ) + e )

 

6:

除Get,Set,构造析构等极其明白易懂的函数外,函数应当加上注释。

个别函数参数或返回值有约定时,应给出注释说明。

函数体超过20行,应当在核心思想处给出注释。

函数的注释建议在函数上方专留一行编写,变量的注释可直接在参数声明或定义后本行编写。

 

7:

类的编写,建议以行为为中心,不要以数据为中心。

 

8:

命名要求使用匈牙利命名法。m_ s_ g_  ms_ gs_  l   n  f  un  dw  b d s us  h

C++实现类以C开头,模版类使用T开头,接口类使用I开头,结构使用S开头。

不要使用 java 风格命名,避免下划线,多个单词的命名,首字母必须大写,命名尽量直观表达意思,不要金山词霸找生僻词。

Private函数可使用 双下划线 为首,例如 __PrivateFunc();  Proteced函数可使用 单下划线 为首。Public函数不需要。

函数参数建议以p_开头,以便于函数体内的局部变量进行区分。

变量名尽量使用 “形容词+名词” 格式,函数名尽量使用“动词+名词”格式。

常量和宏定义,使用全部大写的字母,以下划线分割单词。

 

9:

与零比较时。

整形  ->  if( 0 == nValue )    if( 0 != nValue )

布尔类型 -> if( !bValue )    if( bValue )

指针类型 -> if( NULL == pValue )   if( NULL !- pValue )

浮点类型 -> if(( fValue >= -EPSINON ) && ( fValue <=  EPSINON ))

 

10:

循环效率。

for( int i = 0; i < 1000; ++i )

{

       for( int j = 0; j < 5; ++j )

      {

             Do();

     }

}

不好。建议可能的话,将长循环放在内部,短循环放在外部。

若有if的话,可能的话,将if防止循环之外,避免if对循环的打断。

循环内尽量使用 for( int i = 0; i < n; ++i )   而避免使用 for( int i = 0; i < n + 1; ++i ) 这样的全闭区间。

 

11:

迭代器,若迭代的是标准类型,则无妨。若为结构,则建议使用 ++Ite, 而避免使用 Ite++,可以减少构造的代价。

 

12:

尽全力避免goto.

 

13:

尽量使用 const int MAX_XXX = 100; 去替代 #define MAX_XXX 100

一些有关联的常量,应当给出关联,而非一个值。特别常量,可直接给出值,且在后面给出注释说明。例如

const unsigned int GRID_SIZE = 100;  

const unsigned int GRID_IN_MAP = 25;

const unsigned int MAP_SIZE = GRID_SIZE * GRID_IN_MAP;

const float PAI_RECIP = 0.3183099 // π分之一

尽量使用内联函数替代宏函数。

 

14:

类内的常量不可以 const 定义。例如

class A

{

    const int SIZE = 100;

    int m_nArray[SIZE];    // 不行,类未创建对象前,不知道SIZE多大。

}

若必须类内常量,可使用枚举。例如 enum{ SIZE = 100 };

 

15:

除函数指针外,函数建议在头文件内声明时,除了参数类型,也写上函数名。

无参数的函数建议使用void填充参数。

尽可能的准确使用 const .

若参数为自定义结构或类对象,建议使用地址传递方式,避免值传递带来的临时对象的构造和析构。

 

16:

不要脑残的返回栈上内存……!!!

 

17:

使用任何内存,数组,指针,变量都必须初始化!!!!!!!!

 

18:

对于参数传入的指针,要判断它是否为空!!!!!!!!

 

19:

写new的时候,一定要去写delete,再回来写逻辑。

可能的话,new这块内存所在的函数或类,应当负责delete这块内存,避免A创建分配内存,而由B去负责释放。特别是跨线程的管理更应三思而后行。

 

20:

 数组为参数退化为指针就别让我再说了……

 

21:

重载和覆盖要警惕。

 

22:

尽量使用初始化表进行成员变量初始化,但要注意,若成员变量是自定义类,要确定类的构造顺序。

 类中的const常量只能使用初始化表进行初始化,不能赋值初始化。

若类有继承关系,则子类必须在构造函数内显式的调用基类的构造函数,依旧是建议使用初始化表。

23:

若不希望默认拷贝构造函数和赋值函数,则显式的声明一个空函数,设置为private。避免被人误使用。

 

24:

多考虑继承,组合的选择性。

25:

函数成员变量建议直到需要使用时再声明定义,建议函数成员变量定义时直接赋值为0或NULL,避免空声明。

注意有些函数内返回false时候,之前new的对象的delete。

 

26:

避免操作符按值返回结果。

例如: vector operator+( const vector& v1, const vector& v2 ) 使用起来是方便,但是要创建临时对象并复制,开销太大。

可使用 void operator+( const vector& v1, const vector& v2 ),由V1返回更好。虽然可读性低了,但是代价更低。当然,使用 += 不会出现这种情况,会比直接使用 + 更好。

 

27;

可能的话,避免 dynamic_cast 在开启RTTI的情况下,它才有意义,但是开销巨大。除非被严重继承的类对象使用时,可以考虑这种面向对象的设计方式。(很遗憾,某志还是懒的推荐它。)

 

28:

 使用STL的时候,可能的话,使用vector替代set。 set维护的是一个红黑树,维护它的树结构时的代价经常比算法节省的时间代价大的多。

原创粉丝点击