C++ 代码点评. 简单再简单,遵循C和C++ 编程的原则规范,减少代码Bug admin • 2023年2月9日 上午7:03 • C/C++ • 阅读 151 Gtest代码评审: <内部使用 不讲究格式> for循环问题 Vector t; .... 1.//养成一种习惯 for(int i = 0 ; i <t. Size(); i++ )错误修改为for (int i = 0 ; i <t. Size(); ++i ) { 业务代码 } 在for循环的代码准则请遵循C的数组概念: i从0开始 到<一个数结束[ )格式 for(int i = 1 ; i <=t. Size() -1; ++i )不要这么写,没有任何好处 避免 用do {} while做循环 Testconfig.h文件 #include #include #include #include #include #include #include #include #include #include 原理的头包含文件包含太多没有必要的头文件并且没有按照一定的顺序.建议如下,把系统自带库放在最前面,然后是STL库 然后是第三方库 然后是自己写的库文件 #include #include #include #include #include //删除没有必要的头文件 定义结构体尽量简单 Typedefstruct_serCondition {.... .... }serCondition; TypedefstructserConditionserCondition_t //习惯性定义 修改为: structserCondition {.... .... } 去掉多余的定义.如果要定义 请重启一行 TypedefstructserConditionserCondition_t习惯是放在定义前面 定义类型规范一些, Class Testconfig { .... ... private: voidgetSerConditionbyNode(pugi::xml_nodexmlNode,ServiceDataInfo&servicedatainfo,intflag); pugi::xml_documentm_doc; map<string,ServiceInfo>m_serviceMap; } 修改为: Class Testconfig { .... ... private: voidgetSerConditionbyNode(pugi::xml_nodexmlNode,ServiceDataInfo&servicedatainfo,intflag); Private: pugi::xml_documentm_doc; map<string,ServiceInfo>m_serviceMap; } 函数参数定义,尽量少用pugi::xml_nodexmlNode这种模式 voidgetSerConditionbyNode(pugi::xml_nodexmlNode,ServiceDataInfo&servicedatainfo,intflag) 修改为 voidgetSerConditionbyNode(constpugi::xml_node&xmlNode,ServiceDataInfo&servicedatainfo,intflag); Testconfig.cpp文件 函数 bool TestConfig::getTestByServerName(conststring&serverName,ServiceInfo& serviceInfo) 修改为 ServiceInfo*TestConfig::getTestByServerName(conststring&serverName) { //里面的函数体也做一些相应的修改 if( !serverName.empty() ) { map<string,ServiceInfo>::iteratoriter=m_serviceMap.begin(); iter=m_serviceMap.find(serverName); if(iter!=m_serviceMap.end()) { return&iter->second; } } returnNULL; } 讲一个比较我们编程比较典型例子: intTestConfig::getPackByServiceName(conststring&serviceName,vector<string>&strVe,vector<string>&vExpect) { //vector> veMap; ServiceInfo*serviceinfo=getTestByServerName(serviceName); if(serviceinfo==NULL) { return-1; } if(serviceinfo->headText.size() == 0) { for(inti= 0;i<serviceinfo->serviceData.size(); ++i) { strVe.push_back(""); if(!serviceinfo->serviceData[i].caseResult.empty()) { vExpect.push_back(serviceinfo->serviceData[i].caseResult); } else { vExpect.push_back("0"); } } } else { tr1::unordered_map<string,string>strMap; for(inti= 0;i<serviceinfo->serviceData.size(); ++i) { for(intj= 0;j<serviceinfo->headText.size(); ++j) { if(j<serviceinfo->serviceData[i].cellValue.size() ) { strMap[serviceinfo->headText[j]] =serviceinfo->serviceData[i].cellValue[j]; //strMap[].insert(pair(serviceinfo.serviceName[j],serviceinfo.serviceData[i].CllValue[j])); } else { strMap[serviceinfo->headText[j]] =""; } } strVe.push_back(RequestPackage::encode(strMap)); strMap.clear(); if(!serviceinfo->serviceData[i].caseResult.empty()) { vExpect.push_back(serviceinfo->serviceData[i].caseResult); } else { vExpect.push_back("0"); } } } returnserviceinfo->serviceData.size(); } 这段代码运行没有任何问题,但是如果我们去分析它,问题非常多. 1,函数体里面有 ServiceInfo*serviceinfo=getTestByServerName(serviceName); if(serviceinfo==NULL) { return-1; } 这个代码,那么 就应该在调用 getPackByServiceName(conststring&serviceName,vector<string>&strVe,vector<string>&vExpect); 函数之前获取ServiceInfo*serviceinfo. 那么代码修改如下 getPackByServiceName_1(constServiceInfo*serviceinfo,vector<string>&strVe,vector<string>&vExpect); { for(inti= 0;i<serviceinfo->serviceData.size(); ++i) { strVe.push_back(""); if(!serviceinfo->serviceData[i].caseResult.empty()) { vExpect.push_back(serviceinfo->serviceData[i].caseResult); } else { vExpect.push_back("0"); } } } getPackByServiceName_2(constServiceInfo*serviceinfo,vector<string>&strVe,vector<string>&vExpect); { tr1::unordered_map<string,string>strMap; for(inti= 0;i<serviceinfo->serviceData.size(); ++i) { for(intj= 0;j<serviceinfo->headText.size(); ++j) { if(j<serviceinfo->serviceData[i].cellValue.size() ) { strMap[serviceinfo->headText[j]] =serviceinfo->serviceData[i].cellValue[j]; //strMap[].insert(pair(serviceinfo.serviceName[j],serviceinfo.serviceData[i].CllValue[j])); } else { strMap[serviceinfo->headText[j]] =""; } } strVe.push_back(RequestPackage::encode(strMap)); strMap.clear(); if(!serviceinfo->serviceData[i].caseResult.empty()) { vExpect.push_back(serviceinfo->serviceData[i].caseResult); } else { vExpect.push_back("0"); } } } getPackByServiceName(conststring&serviceName,vector<string>&strVe,vector<string>&vExpect); { ServiceInfo*serviceinfo=getTestByServerName(serviceName); if(serviceinfo==NULL) { return-1; } if(serviceinfo->headText.size() == 0) { getPackByServiceName_1(.....); } Else { getPackByServiceName_2(.....); } returnserviceinfo->serviceData.size(); } 呵呵 简单把 肯定不会出bug 函数代码 参考代码代码 voidTestConfig::getSerConditionbyNode(constpugi::xml_node&xmlNode,ServiceDataInfo&servicedatainfo,intflag)// int flag的多余的 直接修改为 voidTestConfig::getSerConditionbyNode(constpugi::xml_node&xmlNode,ServiceDataInfo&servicedatainfo,std::vector &ServiceData) // std::vector &ServiceData参数进去就没有必要的逻辑判断. 下面的代码是不是多余了 if(serConditionList[i].queOperator.empty()) { vOperator.push_back(""); } else { vOperator.push_back(serConditionList[i].queOperator); } 其实直接用就可以了 vOperator.push_back(serConditionList[i].queOperator); voidTestConfig::getPosServiceData(constServiceDataInfo&serviceDataInfo, 和 voidTestConfig::getPreServiceData(constServiceDataInfo&serviceDataInfo, 以被抽象出来,雷同的代码尽量抽取出来 execQueryTest.cpp问题点 很多时候我们在写代码的时候思维是否混乱的 看看这段代码吧, 大家对照下面这个函数代码 我抽取一段出来 booldoServiceData(constServiceDataInfo&servicedatainfo,intflag,string&serverName,string&pack) if(flag== 0) { testconfig.getPreServiceData(servicedatainfo,preService,strPack,caseResult,vOperator); } else { testconfig.getPosServiceData(servicedatainfo,preService,strPack,caseResult,vOperator); } 在我们开始运用flag标记的时候 我们需要考虑是否真的需要flag.其实很多是没有必要的. 如果真的需要,请把flag放在最后一个参数.OK 这里是没有必要的, 第一,既然知道用参数flag== 0也就知道调用testconfig.getPreServiceData函数. 第二 如果需要在函数体里面调用,请用函数指针.简单明了 减少if判断. for(inti= 0;i<preService.size(); ++i) { rebuffer=csynCallService(preService[i],strPack[i]); serverName=preService[i]; pack=strPack[i]; ReplyPackage::decodeErrorCode(rebuffer,errorCode,errorMessage); if( !preService[i].compare("execQuery")) { Recordsetrecordset;//这个定义要考后 if(errorCode!="0")//这个判断是否应该提前 { returnfalse; } else { ReplyPackage::decodeFirstDataset(rebuffer,recordset); if(!toQueOperator(vOperator[i],recordset.getFieldValue(0, 0),caseResult[i])) { returnfalse; } } } else { if(errorCode!=caseResult[i]) { returnfalse; } } } Return true; 代码修改如下. for(inti= 0;i<preService.size(); ++i) { rebuffer=csynCallService(preService[i],strPack[i]); serverName=preService[i]; pack=strPack[i]; ReplyPackage::decodeErrorCode(rebuffer,errorCode,errorMessage); if(errorCode!=caseResult[i]) { returnfalse; } if(errorCode=="0"&&!preService[i].compare("execQuery")) { Recordsetrecordset; ReplyPackage::decodeFirstDataset(rebuffer,recordset); if(!toQueOperator(vOperator[i],recordset.getFieldValue(0, 0),caseResult[i])) { returnfalse; } } } Return true; 代码逻辑应该清楚一些了吧 函数变量定义原则.只有在需要定义的时候才定义,不要提前定义. mainTest.cpp 大家查看源代码 TEST_F(maintest,tests) 以下是我重写的代码: 重构原则,抽象出相同的代码. voidshowServiceData(vector<serCondition>&ServiceData) { for(intx= 0;x<ServiceData.size(); ++x) { cout<<"posServiceData:"<<endl; for_each(ServiceData[x].headText.begin(),ServiceData[x].headText.end(),ostream_iterator<string>(cout," ")); for_each(ServiceData[x].cellValue.begin(),ServiceData[x].cellValue.end(),ostream_iterator<string>(cout," ")); } } voidshowService(vector<string>&services,vector<string>&caseResult,vector<string>&pack,vector<string>&vOperator) { for(intposIndex= 0;posIndex<services.size();posIndex++) { cout<<"serviceName:"<<services[i] <<endl; cout<<"pack:"<<pack[i] <<endl; cout<<":"<<caseResult[i] <<endl; cout<<"Operator:"<<vOperator[i] <<endl; } } TEST_F(maintest,tests) { //这段代码需要拆分每一个并列的for或者if语句 基本是两件事情,需要用不同的函数进行细分 vector<string>pack; vector<string>preService; vector<string>caseResult; vector<string>vOperator; TestConfigtestconfig; testconfig.init(); stringserverName="login"; ServiceInfo*serviceinfo=testconfig.getTestByServerName(serverName); for(inti= 0;i<serviceinfo->serviceData.size(); ++i) { for(intj= 0;j<serviceinfo->serviceData[i].cellValue.size(); ++j) { cout<<serviceinfo->serviceData[i].cellValue[j] <<endl; } showServiceData(serviceinfo->serviceData[i].posServiceData); cout<<endl; testconfig.getPosServiceData(serviceinfo->serviceData[i],preService,pack,caseResult,vOperator); showService(serviceinfo->serviceData[i],caseResult,pack,vOperator); showServiceData(serviceinfo->serviceData[i].preServiceData); cout<<endl; testconfig.getPosServiceData(serviceinfo->serviceData[i],preService,pack,caseResult,vOperator); showService(serviceinfo->serviceData[i],caseResult,pack,vOperator); cout<<endl<<endl<<endl<<endl<<endl; testconfig.getPreServiceData(serviceinfo->serviceData[i],preService,pack,caseResult,vOperator); showService(serviceinfo->serviceData[i],caseResult,pack,vOperator); cout<<endl; } vector<string>expect; vector<string>strVe; introwTest=testconfig.getPackByServiceName(serverName,strVe,expect); for(inti= 0;i<rowTest; ++i) { cout<<strVe[i] <<endl; cout<<expect[i] <<endl; } }原文链接: https://www.cnblogs.com/willyzhao/archive/2012/07/20/2601040.html 欢迎关注 微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍 原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/56064 非原创文章文中已经注明原地址,如有侵权,联系删除 关注公众号【高性能架构探索】,第一时间获取最新文章 转载文章受原作者版权保护。转载请注明原作者出处! C/C++ 赞 (0) admin 0 0 生成海报 [C/C++]关于C++11中的std::move和std::forward 上一篇 2023年2月9日 上午7:03 从函数或方法返回内存 – C++快速入门35 下一篇 2023年2月9日 上午7:03 相关推荐 Clam and fish 2023年3月2日 OJ在线编程常见输入输出练习场 2023年3月1日 c++类定义代码的分离 2023年2月13日 C++性能优化指南 2023年2月12日 C++ 重载、覆盖和隐藏 2023年2月9日 C++中的类型转换——reinterpret_cast 2023年2月13日