C++ 代码点评. 简单再简单,遵循C和C++ 编程的原则规范,减少代码Bug

Gtest 代码评审: <内部使用 不讲究格式>

 

for 循环问题

Vector <string> t;

....

1. //养成一种习惯 

for(int i = 0 ; i < t. Size(); i++ ) 错误 修改为 for  (int  i  =  0 ; i  < t. Size();  ++i ) 

{

业务代码

}

 

for 循环的代码准则请遵循C的数组概念: i 开始  到 < 一个数结束 [  ) 格式

for(int  i  =  1 ; i  <= t. Size() -1;  ++i )  不要这么写 没有任何好处

避免 用 do {} while 做循环

 

Testconfig.h 文件 

 

#include <iostream>

#include <string>

#include <atmi.h>

#include <ParamTokenizer.h>

#include <exception/TapException.h>

#include <atmiWrapper/ServiceBase.h>

#include <packetWrapper/Recordset.h>

#include <boost/lexical_cast.hpp>

#include <gtest/gtest.h>

#include <boost/algorithm/string.hpp>

 

原理的头包含文件包含太多没有必要的头文件 并且没有按照一定的顺序建议如下, 把系统自带库放在最前面然后是STL 库 然后是第三方库 然后是自己写的库文件

 

#include <string>

#include <map>

#include <vector>

#include <pugixml.hpp>

#include <boost/shared_ptr.hpp>

//删除没有必要的头文件

 

 

 

定义结构体尽量简单

Typedef struct _serCondition

{   ....

....

serCondition;

 

Typedef struct serCondition  serCondition_t //习惯性定义

修改为:

struct serCondition

{   ....

....

去掉多余的定义如果要定义 请重启一行

Typedef struct serCondition  serCondition_t 习惯是放在定义前面

 

定义类型规范一些 

Class  Testconfig 

{

  ....

  ...

private:

void getSerConditionbyNode(pugi::xml_node xmlNodeServiceDataInfoservicedatainfoint flag);

 

    pugi::xml_document m_doc;

map<stringServiceInfom_serviceMap;

}

 

修改为:

Class  Testconfig 

{

  ....

  ...

private:

void getSerConditionbyNode(pugi::xml_node xmlNodeServiceDataInfoservicedatainfoint flag);

 

Private:

    pugi::xml_document m_doc;

 map<stringServiceInfom_serviceMap;

}

 

 

函数参数定义尽量少用pugi::xml_node xmlNode 这种模式

void getSerConditionbyNode(pugi::xml_node xmlNodeServiceDataInfoservicedatainfoint flag)

 

修改为

void getSerConditionbyNode(const pugi::xml_node& xmlNodeServiceDataInfoservicedatainfoint flag);

 

 

Testconfig.cpp 文件

 

 

函数

bool TestConfig::getTestByServerName(const stringserverNameServiceInfo & serviceInfo)

 

修改为

ServiceInfoTestConfig::getTestByServerName(const stringserverName)

{ //里面的函数体也做一些相应的修改

 

if ( !serverName.empty() )

{

map<stringServiceInfo>::iterator iter = m_serviceMap.begin();

iter = m_serviceMap.find(serverName);

if (iter != m_serviceMap.end())

{

return &iter->second;

}

}

return NULL;

}

 

 

讲一个比较我们编程比较典型例子:

 

int TestConfig::getPackByServiceName(const stringserviceNamevector<string>& strVevector<string>& vExpect)

{

//vector<map<string,string>> veMap;

 

ServiceInfoserviceinfo = getTestByServerName(serviceName);

if (serviceinfo == NULL)

{

return -1;

}

 

if (serviceinfo->headText.size() == 0)

{

for (int i = 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<stringstringstrMap;

for (int i = 0; i < serviceinfo->serviceData.size(); ++i)

{

for (int j = 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_backRequestPackage::encode(strMap));

strMap.clear();

 

if (!serviceinfo->serviceData[i].caseResult.empty())

{

vExpect.push_back(serviceinfo->serviceData[i].caseResult);

}

else

{

vExpect.push_back("0");

}

}

}

 

return serviceinfo->serviceData.size();

}

 

这段代码运行没有任何问题但是如果我们去分析它 问题非常多.

 

1, 函数体里面有

ServiceInfoserviceinfo = getTestByServerName(serviceName);

if (serviceinfo == NULL)

{

return -1;

}

这个代码那么 就应该在调用

getPackByServiceName(const stringserviceNamevector<string>& strVevector<string>& vExpect);

函数之前获取  ServiceInfoserviceinfo.

那么代码修改如下

 

getPackByServiceName_1(const ServiceInfoserviceinfovector<string>& strVevector<string>& vExpect);

{

for (int i = 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(const ServiceInfoserviceinfovector<string>& strVevector<string>& vExpect);

{

tr1::unordered_map<stringstringstrMap;

for (int i = 0; i < serviceinfo->serviceData.size(); ++i)

{

for (int j = 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_backRequestPackage::encode(strMap));

strMap.clear();

 

if (!serviceinfo->serviceData[i].caseResult.empty())

{

vExpect.push_back(serviceinfo->serviceData[i].caseResult);

}

else

{

vExpect.push_back("0");

}

}

}

 

getPackByServiceName(const stringserviceNamevector<string>& strVevector<string>& vExpect);

{

    ServiceInfoserviceinfo = getTestByServerName(serviceName);

if (serviceinfo == NULL)

{

return -1;

}

 

if (serviceinfo->headText.size() == 0)

{

getPackByServiceName_1(.....);

}

Else

{

getPackByServiceName_2(.....);

}

return serviceinfo->serviceData.size();

 

}

 

呵呵 简单把 肯定不会出bug

 

函数代码 参考代码<testConfig.cpp> 代码

void TestConfig::getSerConditionbyNode(const pugi::xml_nodexmlNodeServiceDataInfoservicedatainfoint flag)  // int flag 的多余的 直接修改为

 

 

 

void TestConfig::getSerConditionbyNode(const pugi::xml_nodexmlNodeServiceDataInfoservicedatainfostd::vector<string> & ServiceData) 

 // std::vector<string> & ServiceData 参数进去就没有必要的逻辑判断.

 

 

下面的代码是不是多余了 

if (serConditionList[i].queOperator.empty())

{

vOperator.push_back("");

}

else

{

vOperator.push_back(serConditionList[i].queOperator);

}

 

其实直接用就可以了

vOperator.push_back(serConditionList[i].queOperator);

 

 

void TestConfig::getPosServiceData(const ServiceDataInfoserviceDataInfo,

void TestConfig::getPreServiceData(const ServiceDataInfoserviceDataInfo,

以被抽象出来雷同的代码尽量抽取出来

 

 

execQueryTest.cpp 问题点

 

很多时候我们在写代码的时候思维是否混乱的

看看这段代码吧 ,

大家对照下面这个函数代码 我抽取一段出来

bool doServiceData(const ServiceDataInfoservicedatainfoint flagstringserverNamestringpack)

 

if (flag == 0)

{

testconfig.getPreServiceData(servicedatainfopreServicestrPackcaseResultvOperator);

}

else

{

testconfig.getPosServiceData(servicedatainfopreServicestrPackcaseResultvOperator);

}

 

在我们开始运用 flag 标记的时候 我们需要考虑是否真的需要flag. 其实很多是没有必要的.

如果真的需要 请把flag 放在最后一个参数.OK

这里是没有必要的,

 

第一既然知道用参数 flag == 0 也就知道调用 testconfig.getPreServiceData函数.

 

第二 如果需要在函数体里面调用请用函数指针简单明了 减少if 判断

 

for (int i = 0; i < preService.size(); ++i)

{

rebuffer = csynCallService(preService[i], strPack[i]);

serverName = preService[i];

pack = strPack[i];

ReplyPackage::decodeErrorCode(rebuffererrorCodeerrorMessage);

    

    if( !preService[i].compare("execQuery"))

{

Recordset recordset;  / /这个定义要考后

if (errorCode != "0")  //这个判断是否应该提前

{

return false;

}

else

{

ReplyPackage::decodeFirstDataset(rebufferrecordset);

if (!toQueOperator(vOperator[i], recordset.getFieldValue(0, 0), caseResult[i])) 

           {

return false;

}

}

}

else

{

if (errorCode != caseResult[i])

{

return false;

}

}

}

Return true;

 

 

代码修改如下.

for (int i = 0; i < preService.size(); ++i)

{

rebuffer = csynCallService(preService[i], strPack[i]);

serverName = preService[i];

pack = strPack[i];

ReplyPackage::decodeErrorCode(rebuffererrorCodeerrorMessage);

 

if (errorCode != caseResult[i])

{

return false;

}

    

    iferrorCode ="0" && !preService[i].compare("execQuery"))

{

Recordset recordset; 

        ReplyPackage::decodeFirstDataset(rebufferrecordset);

if (!toQueOperator(vOperator[i], recordset.getFieldValue(0, 0), caseResult[i]))

          {

return false;

}

}

}

Return true;

 

代码逻辑应该清楚一些了吧

 

函数变量定义原则只有在需要定义的时候才定义不要提前定义.

 

mainTest.cpp

 

大家查看源代码

TEST_F(maintesttests)

 

以下是我重写的代码:

重构原则抽象出相同的代码

 

void showServiceData(vector<serCondition>& ServiceData)

{

for (int x = 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" "));

}

}

 

void showService(vector<string>& services,vector<string>&caseResult ,vector<string>&pack,vector<string>&vOperator )

{

for (int posIndex = 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(maintesttests)

{

 

//这段代码需要拆分每一个并列的for 或者if 语句 基本是两件事情 ,需要用不同的函数进行细分

vector<stringpack;

vector<stringpreService;

vector<stringcaseResult;

vector<stringvOperator;

 

TestConfig testconfig;

testconfig.init();

string serverName = "login";

ServiceInfoserviceinfo = testconfig.getTestByServerName(serverName);

 

for (int i = 0; i < serviceinfo->serviceData.size(); ++i)

{

for (int j = 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], preServicepackcaseResultvOperator);

showService(serviceinfo->serviceData[i], caseResultpackvOperator );

 

 

showServiceData(serviceinfo->serviceData[i].preServiceData);

cout << endl;

testconfig.getPosServiceData(serviceinfo->serviceData[i], preServicepackcaseResultvOperator);

showService(serviceinfo->serviceData[i], caseResultpackvOperator );

cout << endl << endl << endl << endl << endl;

 

testconfig.getPreServiceData(serviceinfo->serviceData[i], preServicepackcaseResultvOperator);

showService(serviceinfo->serviceData[i], caseResultpackvOperator );

cout << endl;

}

 

vector<stringexpect;

vector<stringstrVe;

int rowTest = testconfig.getPackByServiceName(serverNamestrVeexpect);

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

{

cout << strVe[i] << endl;

cout << expect[i] << endl;

}

}

转载于:https://www.cnblogs.com/willyzhao/archive/2012/07/20/2601040.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值