Tải bản đầy đủ - 0 (trang)
Chapter 15.  Use const proactively

Chapter 15.  Use const proactively

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

Summary

constisyourfriend:Immutablevaluesareeasierto

understand,track,andreasonabout,sopreferconstantsover

variableswhereveritissensibleandmakeconstyourdefault

choicewhenyoudefineavalue:It'ssafe,it'scheckedat

compiletime(seeItem14),andit'sintegratedwithC++'stype

system.Don'tcastawayconstexcepttocallaconst-incorrect

function(seeItem94).



Discussion

Constantssimplifycodebecauseyouonlyhavetolookatwhere

theconstantisdefinedtoknowitsvalueeverywhere.Consider

thiscode:

voidFun(vector&v){

//

constsize_tlen=v.size();

//30morelines

}



Whenseeinglen'sdefinitionabove,yougaininstantconfidence

aboutlen'ssemanticsthroughoutitsscope(assumingthecode

doesn'tcastawayconst,whichitshouldnotdo;seebelow):

It'sasnapshotofv'slengthataspecificpoint.Justbylooking

uponelineofcode,youknowlen'ssemanticsoveritswhole

scope.Withouttheconst,lenmightbelatermodified,either

directlyorthroughanalias.Bestofall,thecompilerwillhelp

youensurethatthistruthremainstrue.

Notethatconstisnotdeep.Forexample,consideraclassC

thathasamemberoftypeX*.InCobjectsthatareconst,the

X*memberisalsoconstbuttheXobjectthatispointedtois

not.(See[Saks99].)

Implementlogicalconstnesswithmutablemembers.Whena

constmemberfunctionofaclasslegitimatelyneedstomodify

amembervariable(i.e.,whenthevariabledoesnotaffectthe

object'sobservablestate,suchascacheddata),declarethat

membervariablemutable.Notethatifallprivatemembersare



hiddenusingthePimplidiom(seeItem43),mutableisnot

neededoneitherthecachedinformationortheunchanging

pointertoit.

Yes,constis"viral"additinoneplace,anditwantsto

propagatethroughoutyourcodeasyoucallotherfunctions

whosesignaturesaren'tyetconst-correct.Thisisafeature,not

abug,andthisqualitygreatlyincreasesconst'spowereven

thoughitwasunjustlydemeanedinthedayswhenconst

wasn'twellunderstoodandappreciated.Retrofittinganexisting

codebasetomakeitconst-correcttakeseffort,butitis

worthwhileandlikelytouncoverlatentbugs.

Const-correctnessisworthwhile,proven,effective,andhighly

recommended.Understandinghowandwhereaprogram'sstate

changesisvital,andconstdocumentsthatdirectlyincode

wherethecompilercanhelptoenforceit.Writingconst

appropriatelyhelpsyougainabetterunderstandingofyour

designandmakesyourcodesturdierandsafer.Ifyoufindit

impossibletomakeamemberfunctionconst,youusuallygain

abetterunderstandingofthewaysinwhichthatmember

functionmightmodifyanobject'sstate.Youmightalso

understandwhichdatamembersbridgethegapbetween

physicalconstnessandlogicalconstness,asnotedinthe

followingExamples.

Nevercastawayconstexcepttocallaconst-incorrectfunction,

orinrarecasesasaworkaroundforlackofmutableonolder

compilers.



Examples

Example:Avoidconstpass-by-valuefunctionparametersin

functiondeclarations.Thefollowingtwodeclarationsareexactly

equivalent:

voidFun(intx);



voidFun(constintx);//redeclaresthesamefunction:



Intheseconddeclaration,theconstisredundant.We

recommenddeclaringfunctionswithoutsuchtop-levelconsts,

sothatreadersofyourheaderfileswon'tgetconfused.

However,thetop-levelconstdoesmakeadifferenceina

function'sdefinitionandcanbesensibletheretocatch

unintendedchangestotheparameter:

voidFun(constintx){//Fun'sactualdefinition

//



++x;//error:cannotmodifyaconstv

//

}



References

[Allison98]Đ10[Cline99]Đ14.02-12[Dewhurst03]Đ6,Đ3132,Đ82[Keffer95]pp.5-6[Koenig97]Đ4[Lakos96]

Đ9.1.6,Đ9.1.12[Meyers97]Đ21[Murray93]Đ2.7

[Stroustrup00]Đ7.2,Đ10.2.6,Đ16.3.1[Sutter00]Đ43



16.Avoidmacros

Summary

Discussion

Examples

Exceptions

References



Summary

TO_PUT_IT_BLUNTLY:MacrosarethebluntestinstrumentofC

andC++'sabstractionfacilities,ravenouswolvesinfunctions'

clothing,hardtotame,marchingtotheirownbeatalloveryour

scopes.Avoidthem.



Discussion

It'shardtofindlanguagethat'scolorfulenoughtodescribe

macros,butwe'lltry.Toquotefrom[Sutter04]Đ31:

Macrosareobnoxious,smelly,sheet-hoggingbedfellows

forseveralreasons,mostofwhicharerelatedtothefact

thattheyareaglorifiedtext-substitutionfacilitywhose

effectsareappliedduringpreprocessing,beforeanyC++

syntaxandsemanticrulescanevenbegintoapply.

Lestthereremainanyambiguityonthispoint,wenotealsothat

BjarneStroustruphaswritten:

Idislikemostformsofpreprocessorsandmacros.Oneof

C++'saimsistomakeC'spreprocessorredundant(Đ4.4,

Đ18)becauseIconsideritsactionsinherentlyerrorprone.

[Stroustrup94]Đ3.3.1

MacrosarealmostnevernecessaryinC++.Useconst

(Đ5.4)orenum(Đ4.8)todefinemanifestconstants[see

Item15],inline(Đ7.1.1)toavoidfunction-calling

overhead[butseeItem8],templates(Chapter13)to

specifyfamiliesoffunctionsandtypes[seeItems64

through67],andnamespaces(Đ8.2)toavoidname

clashes[seeItems57through59].

[Stroustrup00]Đ1.6.1

Thefirstruleaboutmacrosis:Don'tusethemunlessyou

haveto.Almosteverymacrodemonstratesaflawinthe

programminglanguage,intheprogram,orinthe

programmer.



[Stroustrup00]Đ7.8

ThemainproblemwithC++macrosisthattheyseemmuch

betteratwhattheydothantheyreallyare.Macrosignore

scopes,ignorethetypesystem,ignoreallotherlanguage

featuresandrules,andhijackthesymbolsthey#defineforthe

remainderofafile.Macroinvocationslooklikesymbolsor

functioncalls,butareneither.Macrosarenot"hygienic,"

meaningthattheycanexpandtosignificantlyandsurprisingly

differentthingsdependingonthecontextinwhichtheyare

used.Thetextsubstitutionthatmacrosperformmakeswriting

evenremotelypropermacrosablackartwhosemasteryisas

unrewardingasitistedious.

Peoplewhothinkthattemplate-relatederrorsaretheworstto

decipherprobablyhaven'tseenthosecausedbybadlyformed

orbadlyusedmacros.TemplatesarepartofC++'stypesystem

andthusallowcompilerstogetbetterathandlingthem(which

theydo),whereasmacrosareforeverdivorcedfromthe

languageandhenceintractable.Worse,unlikeatemplate,a

macromightexpandtosometransmissionlinenoisethat

undesirablycompilesbypurechance.Finally,anerrorina

macrocanonlybereportedafterthemacroisexpandedand

notwhenitisdefined.

Evenintherarecaseswhereyoudolegitimatelywriteamacro

(seeExceptions),nevereverevenconsiderstartingtothink

aboutwritingamacrothatisacommonwordorabbreviation.

Do#undefinemacrosassoonaspossible,alwaysgivethem

SCREAMING_UPPERCASE_AND_UGLYnames,andavoidputting

theminheaders.



Examples

Example:Passingatemplateinstantiationtoamacro.Macros

barelyunderstandC'sparenthesesandsquarebracketswell

enoughtobalancethem.C++,however,definesanew

parentheticalconstruct,namelytheusedintemplates.

Macroscan'tpairthosecorrectly,whichmeansthatinamacro

invocation

MACRO(Foo)



themacrothinksitisbeingpassedtwoarguments,namely

Foo,wheninfacttheconstructisoneC++

entity.



Exceptions

Macrosremaintheonlysolutionforafewimportanttasks,such

as#includeguards(seeItem24),#ifdefand#ifdefined

forconditionalcompilation,andimplementingassert(seeItem

68).

Forconditionalcompilation(e.g.,system-dependentparts),

avoidlitteringyourcodewith#ifdefs.Instead,preferto

organizecodesuchthattheuseofmacrosdrivesalternative

implementationsofonecommoninterface,andthenusethe

interfacethroughout.

Youmaywanttousemacros(cautiously)whenthealternative

isextremecopyingandpastingsnippetsofcodearound.

Wenotethatboth[C99]and[Boost]includemoderateand

radicalextensions,respectively,tothepreprocessor.



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

Chapter 15.  Use const proactively

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

×