C核心指南I13不要以单独指针

微信客服求职招聘微信群 http://www.guikeyun.com/cms/news/437845.html

理由:

用数组指针+数组大小作为参数的接口很容易出错。指向数组的指针必须依靠其他途径传递其大小。

举例:

//copyfrom[p:p+n)to[q:q+n)voidcopy_n(constT*p,T*q,intn);

如果q的元素数少于n会怎么样?我们会覆盖一些无关的内存。如果p的长度小于n会怎么样?我们可能复制了一些无关的内存。任何一种情况,都导致了未定义的行为,可能是很难处理的bug。

voidmy_copy_n(constchar*p,char*q,intn){for(;n0;n--){*q=*p;p++;q++;}}intmain(){charpp[]="hello";charqq[]="hel";coutqqendl;my_copy_n(pp,qq,5);coutqqendl;charpp1[]="hel";charqq1[]="hello";coutqq1endl;my_copy_n(pp1,qq1,5);coutqq1;turn0;}

helhelloellohellohel

替代方案:

考虑显式地用span

voidcopy(spanconstTr,spanTr2);//copyrtor2反例:voiddraw(Shape*p,intn);//poorinterface;poorcodeCirclearr[10];//...draw(arr,10);

给参数n的值如果是10可能会出错:C语言里数组下标的不成文的习俗是[0:n)即包括0,不包括n。更坏的情况是,调用draw()函数在编译时没有问题,数组隐式的转换成了指针(数组衰减),另一个隐式转换:Circle转成了Shape。draw()函数无法逐个访问数组的元素,因为无从知道元素本身的大小(Shape和Circle大小不一)。

替代方案:

使用支持类,确保元素数量可知,避免危险的隐式转换。

比如:

voiddraw2(spanCircle);Circlearr[10];//...draw2(spanCircle(arr));//deducethenumberofelementsdraw2(arr);//deducetheelementtypeandarraysizevoiddraw3(spanShape);draw3(arr);//error:cannotconvertCircle[10]tospanShape

draw2()得到与draw()同样数量的信息。但是不在会隐式转换Circle类型。

例外:

使用zstring和czstring表示C风格的\0结尾的字符串。这时候,要用GSL的std::string_view或spanchar避免错误的范围。

强化:

(简单)隐式的将数组类型转换成指针类型的地方,报警。允许例外情况:zstring和czstring指针。

(简单)指针类型的数值计算,报警。允许例外情况:zstring和czstring指针。

C++核心指南是由C++创始人BjarneStroustrup和ISO/ANSIC++标准委员会秘书HerbSutter领导开发的关于如何正确高效使用C++的在线文档。就像C++语言本身一样,这些指南是许多组织中许多人多年讨论和设计的结果。

kimim


转载请注明:http://www.aierlanlan.com/grrz/565.html