C++编程规范
一、 类名命名规范及使用约定
C类:普通类(Class)
C+名词的方式命名,名词采用波浪法,必须使用可以明确表达变量意义的英文名词, 以C为前缀,C后第一个字母大写。
这些类一般是根据设计需要,具有一定物理世界映射意义的实体类。设计和封装上必须按照已有的准则进行。
如:
class CGamer
{
}
二、 数据变量命名规范
成员变量的命名规范:
m+_+[变量类型]+变量名
m后带上明确表达变量意义的英文名词而不要用难以表达意义的缩写。且m后的变量名首字母必须大写。如:
class CMyGame
{
private :
TPoint m_Point;<―――普通类型
CGame* m_pGame;<―――指针类型
Int m_nGameID;<―――整数类型
}
函数参数的命名规范:
采用波浪法来定义函数参数变量。同样的,也必须使用可以明确表达变量意义的英文名词,而不仅仅是缩写。
[变量类型]+变量名
如定义一个读取文件的函数,并且用参数传入一个文件名
public boolean readFile(String szFileName)
{
…
m_szFileName = szFileName;
}
局部变量的命名规范:
采用全部小写的方式定义局部变量名。而且尽量用有意义的名词作为变量名。
局部变量不需要在前面增加变量类型标识。
public boolean readFile()
{
String filename = “e.ext”;
}
局部循环变量的命名规范:
用小写的i、j、k依次作为循环变量
如:
for (int i = 0 ; i < 10 ; i ++ )
{
for (int j = 0 ; j <10 ; j ++ )
{
}
}
临时变量的命名规范:
一般情况下尽量使用有意义的变量名,如果是某变量的临时变量,可采用前面增加tmp前缀的方式。如果实在没办法,可采用tmp、temp等作为临时变量名,但不可以过多定义诸如tmp1、tmp2等变量,如果出现此情况,则必定可以采用有意义的名词代替。
int tmpserialno = mSerialNo++;
tmpserialno %= 10;
mSerialNo = tmpserialno;
常量
采用波浪法加K前缀来定义函数参数变量。同样的,也必须使用可以明确表达变量意义的英文名词,而不仅仅是缩写。且K后首字母必须大写
如定义文件名最大长度
const Tint KMaxFileName
枚举常量
采用波浪法加E前缀来定义函数参数变量。同样的,也必须使用可以明确表达变量意义的英文名词,而不仅仅是缩写。且E后首字母必须大写
如定义星期
Enum TWeek
{
EMonday = 1;
……
}
变量定义范围建议:
尽量在变量的有效范围内定义之,如果一个变量仅仅在某个函数内使用到,则把其定义为一个成员变量就是不适合的。在如某些变量只在循环内用到,则应该在循环体内定义之,而不要随意括大其定义范围。
变量类型:
基本类型(保留类型)
char cMyChar;
bool bMyBool;
int nMyInt;
float fMyFloat;
double dMyDouble;
unsigned uMyUnsigned;
long lMyLong;
unsigned long ulMyLong;
指针类型
在变量类前增加p标识,作为标识此变量为指针类型,如:
int *pnKey = NULL;
CDateTime* pDateTime = new CDateTime(0);
数组变量命名规范:
对于数组类型的变量,需要在前面增加Arr的前缀,此前缀需跟在类型标识后面。以标识此为数组变量。如:
int m_nArrKey[100];
double dArrValue[200];
CMyClass ArrStrins[200];
特例:对于char buf[200]这种定义,由于其使用习惯原因,不需要采用数组前缀。
对于数组指针变量,同样在类型前增加p标识。在删除的时候,必须用delete[]的方式删除动态数组,以保证数组内的实例被调用析构函数。
CDateTime* pArrBirthdays = new CDateTime[20];
....
delete[] pArrBirthdays;
int* m_pnArrKeys = new int[20];
三、函数命名规范
函数名称必须采用动词名词的组合形式,函数名称的动词部分采用小写而名词部分采用大写的波浪法
如:int getTopicID()
成员变量最好采用private的定义,另外用getter和setter的函数访问和修改之(在需要考虑程序大小的时候可以忽略此规则)
class CTest
{
private:
TInt mTopicID;
public :
int getTopicID()
{
return m_TopicID;
}
void getTopicID(int aTopicID)
{
mTopicID = aTopicID;
}
}
一个方法只完成一个任务,不要把多个任务放在一个方法中,即使那些任务非常小
四、文件名命名规范
文件的名字需和承载的类之间有一定的关联性,而且常用的公共头文件需要定义得比较简短
文件名采用全部小写的方式,不允许大小写混合的方式
五、其他良好的编程习惯
缩进采用tab而不是用space;tab的缩进显示距离建议为4个空格
用一个空行来分开代码和逻辑的分组;
花括号“{”、“}”需独立一行,而不像if for等可以和括号同一行,而且必须与if等缩进相同的空间
如:if ( test == 1 )
{
}
在每个运算符和括号的前后都空一格。
六、代码注释规范
为了能更好的体现代码即详细设计文档这个意图,在对代码注释的时候,需遵守下列的规范。
对函数/类说明的注释块定义
以/** 开始 */结束,每新行前面需要有一个*,而且后面带空格再加说明。如:
/** 注释段开始
* 对程序或函数API的说明
*/ 注释段结束
public void -被说明的函数API
在注释段中,可以采用一些特别的标签来说明函数的参数、返回、抛出的异常等。一般也是在@Tag 形式出现,下面将讲述到。
函数参数描述标签@param
@param parameter-name description
在@param后依次跟上函数名称,此函数的说明
/**
* @param ID 注册ID名字
*/
void SetID(int ID)
函数返回描述标签@return
@return description
在@return后加上返回值的描述,如各种情况下返回的值说明
/**
* @return 整型代表取得的随机值
*/
int GetRandom()
函数体内注释规范
一般在函数内如果需要注释的话,可采用//的方式进行注释说明,如果多行的注释也建议采用//的方式
七、构造与析构
1、类构造函数,做非资源变量的初始化动作,不进行任何可能出现错误的操作,如分配内存,调用资源等。
2、delete 与new ,free与malloc,delete[] 与new[]必须成对使用,否则不保证会不会出现问题。
八、异常处理
1.对于可能抛出异常的类方法、函数,在注释中说明所抛出异常的类名和产生异常的原因;
注释中采用如下语法
@throws fully-qualified-class-name description
fully-qualified-class-name:方法声明的异常名
description:产生异常的原因
例如:
/**
* 连接数据库
* @throws CSQLException 数据库连接失败,具体原因请根据sqlcode查阅数据库错误代码说明
*/
virtual bool connect()=0;
2、所有的异常抛出都必须以对象形式,而不是能以new 的指针形式。而捕获的时候就可以统一用引用的方式进行捕获。这样在性能和开销方面不会加大的同时,也无需关心指针的删除问题。
try
{
throw CDateTimeException(“datetime format error”);
}
catch (CDateTimeException& e)
{
cout<<e.what()<<end;
}