Tải bản đầy đủ - 0 (trang)
Chapter 40.  Avoid providing implicit conversions

Chapter 40.  Avoid providing implicit conversions

Tải bản đầy đủ - 0trang

Summary

Notallchangeisprogress:Implicitconversionscanoftendo

moredamagethangood.Thinktwicebeforeprovidingimplicit

conversionstoandfromthetypesyoudefine,andprefertorely

onexplicitconversions(explicitconstructorsandnamed

conversionfunctions).



Discussion

Implicitconversionshavetwomainproblems:

Theycanfireinthemostunexpectedplaces.

Theydon'talwaysmeshwellwiththerestofthelanguage.

Implicitlyconvertingconstructors(constructorsthatcanbe

calledwithoneargumentandarenotdeclaredexplicit)

interactpoorlywithoverloadingandfosterinvisibletemporary

objectsthatpopupallover.Conversionsdefinedasmember

functionsoftheformoperatorT(whereTisatype)areno

bettertheyinteractpoorlywithimplicitconstructorsandcan

allowallsortsofnonsensicalcodetocompile.Examplesare

embarrassinglynumerous(seeReferences).Wementiononly

two(seeExamples).

InC++,aconversionsequencecanincludeatmostoneuserdefinedconversion.However,whenbuilt-inconversionsare

addedtothemix,theresultscanbeextremelyconfusing.The

solutionissimple:

Bydefault,writeexplicitonsingle-argumentconstructors

(seealsoItem54):



classWidget{//

explicitWidget(unsignedintwidgetizationFactor);

explicitWidget(constchar*name,constWidget*other=0

};



Usenamedfunctionsthatofferconversionsinsteadof



conversionoperators:



classString{//

constchar*as_char_pointer()const;//inthegrand

};



SeealsothediscussionofexplicitcopyconstructorsinItem

54.



Examples

Example1:Overloading.SayyouhaveaWidget::Widget(

unsignedint)thatcanbeinvokedimplicitly,andaDisplay

functionoverloadedforWidgetsanddoubles.Considerthe

followingoverloadresolutionsurprise:

voidDisplay(double);//displaysadouble

voidDisplay(constWidget&);//displaysaWidget



Display(5);//oops:createsanddispla



Example2:Errorsthatwork.Sayyouprovideoperatorconst

char*foraStringclass:

classString{

//

public:

operatorconstchar*();//deplorableform

};



Suddenly,alotofsillyexpressionsnowcompile.Assumes1,s2

areStrings:



intx=s1-s2;//compiles;undefinedbehavior

constchar*p=s1-5;//compiles;undefinedbehavior

p=s1+'0';//compiles;doesn'tdowhatyo

if(s1=="0"){...}//compiles;doesn'tdowhatyo



Thestandardstringwiselyavoidsanoperatorconstchar*

forexactlythisreason.



Exceptions

Whenusedsparinglyandwithcare,implicitconversionscan

makecallingcodeshortandintuitive.Thestandard

std::stringdefinesanimplicitconstructorthattakesaconst

char*.Thisworksfinebecausethedesignerstooksome

precautions:

Thereisnoautomaticconversiontoconstchar*;that

conversionisprovidedthroughtwonamedfunctions,c_str

anddata.

Allcomparisonoperatorsdefinedforstd::string(e.g.,==,

!=,<)areoverloadedtocompareaconstchar*anda

std::stringinanyorder(seeItem29).Thisavoidsthe

creationofhiddentemporaryvariables.

Evenso,therecanstillbesomeweirdnesswithoverloaded

functions:

voidDisplay(int);

voidDisplay(std::string);

Display(NULL);//callsDisplay(int)



Thisresultmightbesurprising.(Incidentally,ifitdidcall

Display(std::string),thecodewouldhaveexhibited

undefinedbehaviorbecauseit'sillegaltoconstructa

std::stringfromanullpointer,butitsconstructorisn't

requiredtocheckforthenull.)



References

[Dewhurst03]Đ36-37[Lakos96]Đ9.3.1[Meyers96]Đ5

[Murray93]Đ2.4[Sutter00]Đ6,Đ20,Đ39



41.Makedatamembersprivate,exceptin

behaviorlessaggregates(C-stylestructs)

Summary

Discussion

Examples

Exceptions

References



Summary

They'renoneofyourcaller'sbusiness:Keepdatamembers

private.OnlyinthecaseofsimpleC-stylestructtypesthat

aggregateabunchofvaluesbutdon'tpretendtoencapsulateor

providebehavior,makealldatamemberspublic.Avoidmixesof

publicandnonpublicdata,whichalmostalwayssignala

muddleddesign.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 40.  Avoid providing implicit conversions

Tải bản đầy đủ ngay(0 tr)

×