研发中心产品一部C++编码规范.docx

上传人:b****7 文档编号:10621333 上传时间:2023-02-21 格式:DOCX 页数:38 大小:52.17KB
下载 相关 举报
研发中心产品一部C++编码规范.docx_第1页
第1页 / 共38页
研发中心产品一部C++编码规范.docx_第2页
第2页 / 共38页
研发中心产品一部C++编码规范.docx_第3页
第3页 / 共38页
研发中心产品一部C++编码规范.docx_第4页
第4页 / 共38页
研发中心产品一部C++编码规范.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

研发中心产品一部C++编码规范.docx

《研发中心产品一部C++编码规范.docx》由会员分享,可在线阅读,更多相关《研发中心产品一部C++编码规范.docx(38页珍藏版)》请在冰豆网上搜索。

研发中心产品一部C++编码规范.docx

研发中心产品一部C++编码规范

北京山海经纬信息技术有限公司

产品一部C++编码规范

 

更新时间:

2009.07

版本:

V2.0.0.0

发布人:

李欣

1.目标

保证程序清晰易读,易于维护,保证产品的可持续性发展

养成良好的编程习惯,减少出错的可能性,提升产品质量

(代码是一项艺术品,程序员是一个专业人员,一个好的习惯利于人利于己)

2.总体原则

代码要简洁、易懂、美观

风格要统一、一致

3.编码规范

1)代码的对齐与缩进

描述:

这是一项美观性方面的要求,但实际上很大程度影响着代码的可读性。

具体要求:

同一级别代码要垂直对齐

不同级别代码要有正确的缩进,缩进应使用Tab键。

起始与终止的花括号“{}”应具有相同的缩进距离,并且均各自处于单独一行,该行不应有其它代码。

示例:

voidCTestDlg:

:

OnButton1()

{

inti=0;

}

if(pDBDriver==NULL)

return;

if(pDBDriver==NULL)

{

MessageBox("failed");

return;

}

try

{

......

}

catch(longerrCode)

{

}

while(pDBDriver->FetchRecord(rec)==S_OK)

{

longid;

pDBDriver->GetField_Int32(rec,0,&id);

}

while(pDBDriver->FetchRecord(rec)==S_OK)

{

if(++count<600000)

continue;

longid;

pDBDriver->GetField_Int32(rec,0,&id);

if(count>=600100)

break;

}

for(j=0;j<100;j++)

{

pClob[j]='A'+(j%26);

}

switch(type)

{

case0:

{

......

}

break;

case1:

{

......

}

break;

case2:

{

......

}

break;

}

typedefenum

{

EnumRWM_Unknown=0,//unknown

EnumRWM_Append,//appendrecord

EnumRWM_Update,//updaterecord

EnumRWM_Delete,//deleterecord

}

EnumRecordWriteMode;

enumEnumType

{

a=1,

b=2,

};

classCLog

{

public:

virtualvoidWriteLog(constchar*pLine)=0;

virtualvoidWriteText(constchar*pText)=0;

};

2)代码中的空行

描述:

代码中合理的空行同样保证程序的清晰易读。

代码简洁不意味着要删除空行,行数的多少与代码是否简洁无关

具体要求:

在函数体与函数体之间应有空行

在一个函数体内部,应有合适的空行,表示函数体功能的实现是分步进行的

在头文件中声明函数或者变量时,相互无关的函数或变量声明之间通常应有空行

相互关联紧密的语句之间不要有空行,如elseif与elseif之间不能有空行。

一般不应有两个以上连续的空行出现

示例:

classCEzRuleLength:

publicCEzRule

{

public:

CEzRuleLength();

virtual~CEzRuleLength();

public:

virtualEnumEzRuleTypeGetType();

virtualEnumEzRuleCatGetCategory();

virtualvoidGetName(char*pName);

virtualvoidPrepare(void*pDBCnn,longDBCnn);

virtualboolCheckRecord(CEzRecordset*pRecordset,longindex);

virtuallongGetSupportFieldType();

private:

intm_iMinLength;

intm_iMaxLength;

};

EnumEzRuleTypeCEzRuleLength:

:

GetType()

{

returnenum_EzRT_Prop_Length;

}

EnumEzRuleCatCEzRuleLength:

:

GetCategory()

{

returnenum_EzRC_Prop;

}

//开始检查

boolbPass=true;

intfc=m_arrFieldIndex.size();

for(inti=0;i

{

CFieldValue*pFV=pRecord->GetFieldValue(m_arrFieldIndex[i]);

if(pFV->bIsNull)

continue;

if((pFV->type&GetSupportFieldType())==0)

{

charmsg[MAX_RULE_NAME+512];

sprintf(msg,"规则\"%s\"应用的字段\"\"类型不正确,无法检查",

m_strUserName,m_arrApplyField[i].c_str());

stException*p=newstException(

EnumError_Failed,__LINE__,__FILE__,msg,0);

throwp;

}

intlength=0;

switch(pFV->type)

{

caseEnumFType_Int8:

caseEnumFType_Int16:

caseEnumFType_Int32:

caseEnumFType_Int64:

{

charbuf[64];

if(pFV->type==EnumFType_Int8)

itoa(pFV->btValue,buf,10);

elseif(pFV->type==EnumFType_Int16)

itoa(pFV->sValue,buf,10);

elseif(pFV->type==EnumFType_Int32)

itoa(pFV->lValue,buf,10);

else

_i64toa(pFV->i64Value,buf,10);

intsize=strlen(buf);

for(inti=0;i

{

if(isdigit(buf[i]))

length++;

}

}

break;

caseEnumFType_String:

{

length=strlen(pFV->pText);

}

break;

}

if(lengthm_iMaxLength)

{

bPass=false;

break;

}

}

3)代码中的换行

描述:

过长的代码很难阅读,需要适当的换行。

一些合理的换行可大大提升代码可读性。

具体要求:

过长的字符串常量可以换行

过长的条件判断语句、函数调用可以换行

当一个函数参数很多时,为了清晰注释每个参数含义,也可每个参数单独一行

换行的位置在“&&”、“||”、“+”、“-”、“*”、“/”,“,”等之后。

换行均应缩进。

但不要把两个很短的语句放在同一行(如在一行中:

min=100;max=0;)。

示例:

return(EnumFType_Int8|EnumFType_Int16|

EnumFType_Int32|EnumFType_Int64|EnumFType_String);

sprintf(

pBuf,

"警告:

%s,代码:

%d,描述:

%s,出错模块ID:

%d,文件:

%s,行号:

%d\r\n",

pText,pException->code,pException->desp,pException->ModuleID,

fname,pException->linenumber);

if((st&EnumProcStatus_NeedInput)!

=0&&

target.iTargetInputIndex==input)

if((status&EnumProcStatus_NeedInput)!

=0||

(status&EnumProcStatus_NeedInputRestart)!

=0)

{

}

constchar*pStr="TheMSDNLibraryistheessentialreference"

"fordevelopers,withmorethan1.5gigabytesof"

"technicalprogramminginformation,samplecode,";

4)代码中的空格

描述:

适当的空格提升代码可读性,因此推荐在代码中使用合理的空格。

具体要求:

“+”、“-”、“*”、“”、“&&”、“&”等运算符两侧推荐使用空格隔开

函数调用时各个参数之间推荐使用空格隔开

只用一个空格进行隔开

示例:

if((pFV->type&GetSupportFieldType())==0)

{

charmsg[MAX_RULE_NAME+512];

sprintf(msg,"规则\"%s\"应用的字段\"\"类型不正确,无法检查",

m_strUserName,m_arrApplyField[i].c_str());

stException*p=newstException(

EnumError_Failed,__LINE__,__FILE__,msg,0);

throwp;

}

5)注释的添加

描述:

注释描述代码的意图。

具体要求:

注释用于描述代码的意图,不是用于将代码注释掉,没有用的代码要删除,不存在模棱两可的代码。

一个类的注释应在头文件中,类的声明之前进行注释。

一个类的成员变量应在头文件中进行注释,一般在成员变量声明的前一行加注释,并且后面应空行。

一个类的成员函数一般在cpp文件中进行注释,注释内容包括函数的意图、参数的含义、返回值的含义、是否抛出异常、供谁调用、调用前要求等等。

If/elseif/case等

函数体中局部变量的注释可以直接写在局部变量声明的后面,位于同一行。

函数比较复杂时,可以分步骤增加注释,以便处理过程清晰易懂。

如果变量的含义可以从名称上很明显获得,可以不加注释;如果返回值含义可以从类型上或者函数名称上很明显获得,可以不加注释;当使用一个整型、不同数值代表不同含义时,此时必须增加注释清晰说明。

示例:

public:

//约束方式

//0:

第n级代码长度为前面级别定义的所有代码长度之和,默认

//例如01,01002,010020001,分别为三个级别的代码

//1:

第n级代码长度为第n级定义的代码长度

//例如01,002,0001,分别为三个级别的代码

longm_iClassType;

//

//代码是否已被使用

//

boolCDlgStdCodeDefine:

:

IsCodeUsed(DBDrv:

:

IDBDriver*pDBDriver,longDBCnn,LPCTSTRlpszCode,longStdID)

{

//

//getthisformatadaptercapability,returnEnumAdapterCap

//

longCShpAdapter:

:

GetCap()

{

return(EnumCap_CanRead|//是否支持读取

EnumCap_CanWrite|//是否支持写入

EnumCap_IsGeoFormat|//是否可存空间数据

EnumCap_HasProjection|//是否具有投影信息

EnumCap_CanUpdate|//是否支持对现有数据更新

EnumCap_HasAttribute|//是否支持属性

EnumCap_CanIndexRecord|//支持索引记录

EnumCap_CanUpdateRecord|//支持更新记录

EnumCap_CanExecuteSQL|//支持sql查询

EnumCap_CanAppend);

}

if(m_hShape==NULL||m_hDBF==NULL)

{

stException*p=newstException(

EnumError_NotOpen,__LINE__,__FILE__,"数据未打开",m_ID);

throwp;

}

bHasFilter=false;//donotsupportsqlfilter

if(m_iRecordIndex>=m_iTotalRecordCount)

{

bReachEnd=true;

return;

}

bReachEnd=false;

CRecord*pRecord=newCRecord();

//getshape

CFieldValue*pShapeField;

OGRGeometry*pOGRGeo=SHPReadOGRObject(m_hShape,m_iRecordIndex);

if(pOGRGeo==NULL)//nullshape

{

pShapeField=newCFieldValue(0,m_arrSrcFields[0].c_str(),(CGeometry*)NULL,false);

}

else

{

OGREnvelopeenv;

pOGRGeo->getEnvelope(&env);

if(env.MinX<-1E300||env.MaxX>1E300)

{

OGRGeometryFactory:

:

destroyGeometry((OGRGeometry*)pOGRGeo);

pShapeField=newCFieldValue(0,m_arrSrcFields[0].c_str(),(CGeometry*)NULL,false);

}

else

{

CGeometry*pGeo=newCGeometry(pOGRGeo);

pShapeField=newCFieldValue(0,m_arrSrcFields[0].c_str(),pGeo,false);

}

}

pRecord->AddFieldValue(pShapeField);

//adddbffields

6)变量的声明和初始化

描述:

如何定义变量及注意事项。

具体要求:

在一个类中成员变量的声明要都放在一起(ClassWizard维护的变量例外),一般声明在类的最后,不要和函数穿插着定义。

一个类中声明的变量,如其类型为基本类型(如int,double,指针,bool等)需要在构造函数中初始化,如其类型为class(如CString,智能指针,Array等)或者struct等,如果有构造函数则一般不需要初始化,总之不让类的变量处在不可知的状态下。

在类的析构函数中必须释放指针等对象,一旦定义指针,就要初始化,一旦初始化,就要在析构中加上释放。

在一个函数中局部变量尽量在用到的时候再定义,以利于别人理解代码。

函数中的局部变量根据情况看是否需要初始化。

一个较大类的成员变量应以“m_”开头,一个很简单类或者结构的成员变量可不以“m_”开头,一个函数体内部的局部变量或者函数参数不能以“m_”开头。

通常在成员变量名称的选择上,遵守以下规则:

Bool类型以m_b开头

整型应以m_i开头

double以m_d开头

float以m_f开头

string以m_str开头

一层指针以m_p开头

两层指针以m_pp开头

智能指针以m_p或者m_ptr开头

数组以m_arr开头

示例:

classCPageSelectTable:

publicCPropertyPage

{

DECLARE_DYNCREATE(CPageSelectTable)

public:

CPageSelectTable();

~CPageSelectTable();

//{{AFX_DATA(CPageSelectTable)

enum{IDD=IDD_DIALOG_SELECT_TABLE};

CListCtrlm_List;

BOOLm_bOwner;

intm_iViewType;

//}}AFX_DATA

//{{AFX_VIRTUAL(CPageSelectTable)

public:

virtualBOOLOnSetActive();

virtualBOOLOnWizardFinish();

protected:

virtualvoidDoDataExchange(CDataExchange*pDX);

//}}AFX_VIRTUAL

protected:

voidFillList();

//{{AFX_MSG(CPageSelectTable)

virtualBOOLOnInitDialog();

afx_msgvoidOnCheckOwner();

afx_msgvoidOnRadioTable();

afx_msgvoidOnRadioTable2();

afx_msgvoidOnChangeEditFilter();

afx_msgvoidOnButtonVer();

afx_msgBOOLOnHelpInfo(HELPINFO*pHelpInfo);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

public:

boolm_bAllowMultipleSelect;

//selectedtablename

CStringArraym_arrSelectTableName;

//page1pointer

CPageAdoAdapter*m_pPage1;

//sdepagepointer

CPageSDECnn*m_pPageSDE;

//所选择SDE版本

CStringm_strVersion;

//所选图层的LayerIndex

longm_iSelLayerIndex;

};

7)函数的声明及实现

描述:

定义函数的注意事项。

具体要求:

在一个类中函数的声明都放在一起(ClassWizard维护的变量例外),一般声明在类的前面,不要和变量穿插着定义。

严格来说,大部分函数都应该有返回值,至少表示成功或者失败。

函数名称的选择应简明并且清晰,并且单词与单词之间应该有大小写的变化,如FindField、LoadFromXML、SaveToXML、RemoveAllFields等等。

函数的功能应尽量简单、明确、不应过长,在编写函数时要考虑其以后的重用性。

除了特别简单的函数之外,函数体内应只有一个return语句,并将其放在最后,见下面示例。

在我们刚开始写一个程序时,有些功能没有封装为一个函数的必要,但是程序在不断的维护、完善过程中,很可能发现一些重复功能可封装为函数供重复调用,此时需仔细考虑函数的封装、重构等,合适的函数封装可大大提升开发效率并减少出错可能。

示例:

//

//规则定义

//

classCEzRule

{

public:

CEzRule();

virtual~CEzRule();

virtualEnumEzRuleTypeGetType()=0;

virtualEnumEzRuleCatGetCategory()=0;

virtualvoidGetName(char*pName)=0;

virtualvoidLoadFromXml(IUnknown*pRawElement);

virtualvoidSaveToXml(IUnknown*pRawDoc,IUnknown**ppRawElement);

virtualconstchar*GetUserName();

virtualvoidSetUserName(constchar*pName);

virtualvoidSetParam(CEzRuleParamSet¶ms);

virtualCEzRuleParamSet*GetParam();

virtuallongGetCap();

virtualvoidAddAuxRecord(CRecord*pRecord);

virtualboolCheckRecord(CEzRecordset*pRecordset,longindex);

virtuallongGetSupportFieldType();

virtualvoidPrepare(void*pDBCnn,longDBCnn);

voidAddApplyField(constchar*pFieldName);

protected:

//自定义名称

charm_strUserName[MAX_RULE_NAME];

//设置参数

CEzRuleParam

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1