一、 类名命名规范及使用约定
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;
有关项目的全局变量用g_开始,类成员变量用m_,局部变量若函数较大则可考虑用l_用以显示说明其是局部变量。
前缀 类型 例子
g_ 全局变量 g_Servers
C 类或者结构体 CDocument,CPrintInfo
m_ 成员变量 m_pDoc,m_nCustomers
c_ 常量
s_ 静态变量
ch char 8位字符 chGrade
ch TCHAR 如果_UNICODE定义,则为16位字符 chName
b BOOL 布尔值 bEnable
n int 整型(其大小依赖于操作系统) nLength
n UINT 无符号值(其大小依赖于操作系统) nHeight
w WORD 16位无符号值 wPos
l LONG 32位有符号整型 lOffset
dw DWORD 32位无符号整型 dwRange
p * 指针 pDoc
lp FAR* 远指针 lpszName
lpsz LPSTR 32位字符串指针 lpszName
lpsz LPCSTR 32位常量字符串指针 lpszName
lpsz LPCTSTR 如果_UNICODE定义,则为32位常量字符串指针 lpszName
h handle Windows对象句柄 hWnd
lpfn callback 指向CALLBACK函数的远指针
sz,str│以0字节终止的字符串 lp │32位的长整数指针
类型和常量的命名 所有的类型和常量都是大写字母,但名字中可以允许使用下划线。
例如:
const LONG NUM_SECTORS = 100;//a C++ style constant
#define MAX_CELLS 64;//a C style constant
#define POWERUNIT 100;//a C style constant
typedef unsigned char UCHAR;//a user defined type
变量定义范围建议:
尽量在变量的有效范围内定义之,如果一个变量仅仅在某个函数内使用到,则把其定义为一个成员变量就是不适合的。在如某些变量只在循环内用到,则应该在循环体内定义之,而不要随意括大其定义范围。
变量类型:
基本类型(保留类型)
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];
MFC、句柄、控件及结构的命名规范
Windows类型 样本变量 MFC类 样本变量
HWND hWnd; CWnd* pWnd;
HDLG hDlg; CDialog* pDlg;
HDC hDC; CDC* pDC;
HGDIOBJ hGdiObj; CGdiObject* pGdiObj;
HPEN hPen; CPen* pPen;
HBRUSH hBrush; CBrush* pBrush;
HFONT hFont; CFont* pFont;
HBITMAP hBitmap; CBitmap* pBitmap;
HPALETTE hPaltte; CPalette* pPalette;
HRGN hRgn; CRgn* pRgn;
HMENU hMenu; CMenu* pMenu;
HWND hCtl; CState* pState;
HWND hCtl; CButton* pButton;
HWND hCtl; CEdit* pEdit;
HWND hCtl; CListBox* pListBox;
HWND hCtl; CComboBox* pComboBox;
HWND hCtl; CScrollBar* pScrollBar;
HSZ hszStr; CString pStr; POINT pt;
CPoint pt; SIZE size; CSize size;
RECT rect; CRect rect;
三、函数命名规范
函数名称必须采用动词名词的组合形式,函数名称的动词部分采用小写而名词部分采用大写的波浪法
如: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 )
{
}
在每个运算符和括号的前后都空一格。
六、代码注释规范
引用一: 文件开头的注释模板
/******************************************************************
** 文件名:
** Copyright(c) 1998-1999 *********公司技术开发部
** 创建人:
** 日 期:
** 修改人:
** 日 期:
** 描 述:
**
** 版 本:
**--------------------------------------------------------------------------
******************************************************************/
引用二: 函数开头的注释模板
/*****************************************************************
** 函数名:
** 输 入: a,b,c
** a---
** b---
** c---
** 输 出: x---
** x 为 1, 表示...
** x 为 0, 表示...
** 功能描述:
** 全局变量:
** 调用模块:
** 作 者:
** 日 期:
** 修 改:
** 日 期:
** 版本
****************************************************************/
引用三: 程序中的注释模板
/*----------------------------------------------------------*/
/* 注释内容 */
/*----------------------------------------------------------*/
七、构造与析构
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;
}