Openedneverletgo

neverletgo  时间:2021-01-15  阅读:()
__AppendixEStandard-LibraryExceptionSafetyEverythingwillworkjustasyouexpectitto,unlessyourexpectationsareincorrect.
–HymanRosenExceptionsafety—exception-safeimplementationtechniques—representingresources—assignment—ppuusshh__bbaacckk()—constructorsandinvariants—standardcontainerguarantees—insertionandremovalofelements—guaranteesandtradeoffs—sswwaapp()—initializationanditerators—referencestoelements—predicates—ssttrriinnggss,streams,algorithms,vvaallaarrrraayy,andccoommpplleexx—theCstandardlibrary—implicationsforlibraryusers—advice—exercises.
E.
1IntroductionStandard-libraryfunctionsofteninvokeoperationsthatausersuppliesasfunctionortemplateargu-ments.
Naturally,someoftheseuser-suppliedoperationswilloccasionallythrowexceptions.
Otherfunctions,suchasallocatorfunctions,canalsothrowexceptions.
Consider:vvooiiddff(vveeccttoorr&vv,ccoonnssttXX&gg){vv[22]=gg;//X'sassignmentmightthrowanexceptionvv.
ppuusshh__bbaacckk(gg);//vector'sallocatormightthrowanexceptionssoorrtt(vv.
bbeeggiinn(),vv.
eenndd());//X'sless-thanoperationmightthrowanexceptionvveeccttoorruu=vv;//X'scopyconstructormightthrowanexception//.
.
.
//udestroyedhere:wemustensurethatX'sdestructorcanworkcorrectly}TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
936Standard-LibraryExceptionSafetyAppendixEWhathappensiftheassignmentthrowsanexceptionwhiletryingtocopyggWillvvbeleftwithaninvalidelementWhathappensiftheconstructorthatvv.
ppuusshh__bbaacckk()usestocopyggthrowsssttdd::bbaadd__aallllooccHasthenumberofelementschangedHasaninvalidelementbeenaddedtothecontainerWhathappensifXX'sless-thanoperatorthrowsanexceptionduringthesortHavetheelementsbeenpartiallysortedCouldanelementhavebeenremovedfromthecontainerbythesortingalgorithmandnotputbackFindingthecompletelistofpossibleexceptionsinthisexampleisleftasanexercise(§E.
8[1]).
Explaininghowthisexampleiswellbehavedforeverywell-definedtypeXX–evenanXXthatthrowsexceptions–ispartoftheaimofthisappendix.
Naturally,amajorpartofthisexplanationinvolvesgivingmeaningandeffectiveterminologytothenotionsof''wellbehaved''and''welldefined''inthecontextofexceptions.
Thepurposeofthisappendixisto[1]identifyhowausercandesigntypesthatmeetthestandardlibrary'srequirements,[2]statetheguaranteesofferedbythestandardlibrary,[3]statethestandard-libraryrequirementsonuser-suppliedcode,[4]demonstrateeffectivetechniquesforcraftingexception-safeandefficientcontainers,and[5]presentafewgeneralrulesforexception-safeprogramming.
Thediscussionofexceptionsafetynecessarilyfocusesonworst-casebehavior.
Thatis,wherecouldanexceptioncausethemostproblemsHowdoesthestandardlibraryprotectitselfanditsusersfrompotentialproblemsAnd,howcanusershelppreventproblemsPleasedon'tletthisdiscussionofexception-handlingtechniquesdistractfromthecentralfactthatthrowinganexcep-tionisthebestmethodforreportinganerror(§14.
1,§14.
9).
Thediscussionofconcepts,tech-niques,andstandard-libraryguaranteesisorganizedlikethis:§E.
2discussesthenotionofexceptionsafety.
§E.
3presentstechniquesforimplementingefficientexception-safecontainersandoperations.
§E.
4outlinestheguaranteesofferedforstandard-librarycontainersandtheiroperations.
§E.
5summarizesexception-safetyissuesforthenon-containerpartsofthestandardlibrary.
§E.
6reviewsexceptionsafetyfromthepointofviewofastandard-libraryuser.
Asever,thestandardlibraryprovidesexamplesofthekindsofconcernsthatmustbeaddressedindemandingapplications.
Thetechniquesusedtoprovideexceptionsafetyforthestandardlibrarycanbeappliedtoawiderangeofproblems.
E.
2ExceptionSafetyAnoperationonanobjectissaidtobeexceptionsafeifthatoperationleavestheobjectinavalidstatewhentheoperationisterminatedbythrowinganexception.
Thisvalidstatecouldbeanerrorstaterequiringcleanup,butitmustbewelldefinedsothatreasonableerror-handlingcodecanbewrittenfortheobject.
Forexample,anexceptionhandlermightdestroytheobject,repairtheobject,repeatavariantoftheoperation,justcarryon,etc.
Inotherwords,theobjectwillhaveaninvariant(§24.
3.
7.
1),itsconstructorswillestablishthatinvariant,allfurtheroperationsmaintainthatinvariantevenifanexceptionisthrown,anditsdestructorwilldofinalcleanup.
Anoperationshouldtakecarethattheinvariantismaintainedbeforethrowinganexception,sothattheobjectisinavalidstate.
However,itisquitepossibleforTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
2ExceptionSafety937thatvalidstatetobeonethatdoesn'tsuittheapplication.
Forexample,astringmayhavebeenleftastheemptystringoracontainermayhavebeenleftunsorted.
Thus,''repair''meansgivinganobjectavaluethatismoreappropriate/desirablefortheapplicationthantheoneitwasleftwithafteranoperationfailed.
Inthecontextofthestandardlibrary,themostinterestingobjectsarecon-tainers.
Here,weconsiderunderwhichconditionsoperationsonstandard-librarycontainerscanbecon-sideredexceptionsafe.
Therecanbeonlytwoconceptuallyreallysimplestrategies:[1]''Noguarantees:''Ifanexceptionisthrown,anycontainerbeingmanipulatedispossiblycorrupted.
[2]''Strongguarantee:''Ifanexceptionisthrown,anycontainerbeingmanipulatedremainsinthestateinwhichitwasbeforethestandard-libraryoperationstarted.
Unfortunately,bothanswersaretoosimpleforrealuse.
Alternative[1]isunacceptablebecauseitimpliesthatafteranexceptionisthrownfromacontaineroperation,thecontainercannotbeaccessed;itcan'tevenbedestroyedwithoutfearofrun-timeerrors.
Alternative[2]isunacceptablebecauseitimposesthecostofroll-backsemanticsoneveryindividualstandard-libraryoperation.
Toresolvethisdilemma,theC++standardlibraryprovidesasetofexception-safetyguaranteesthatsharetheburdenofproducingcorrectprogramsbetweenimplementersofthestandardlibraryandusersofthestandardlibrary:[3a]''Basicguaranteeforalloperations:''Thebasicinvariantsofthestandardlibraryaremaintained,andnoresources,suchasmemory,areleaked.
[3b]''Strongguaranteeforkeyoperations:''Inadditiontoprovidingthebasicguarantee,eithertheoperationsucceeds,orhasnoeffects.
Thisguaranteeisprovidedforkeylibraryopera-tions,suchasppuusshh__bbaacckk(),single-elementiinnsseerrtt()onalliisstt,anduunniinniittiiaalliizzeedd__ccooppyy()(§E.
3.
1,§E.
4.
1).
[3c]''Nothrowguaranteeforsomeoperations:''Inadditiontoprovidingthebasicguarantee,someoperationsareguaranteednottothrowanexceptionThisguaranteeisprovidedforafewsimpleoperations,suchassswwaapp()andppoopp__bbaacckk()(§E.
4.
1).
Boththebasicguaranteeandthestrongguaranteeareprovidedontheconditionthatuser-suppliedoperations(suchasassignmentsandsswwaapp()functions)donotleavecontainerelementsininvalidstates,thatuser-suppliedoperationsdonotleakresources,andthatdestructorsdonotthrowexcep-tions.
Forexample,considerthese''handle-like''(§25.
7)classes:tteemmppllaatteeccllaassssSSaaffee{TT*pp;//ppointstoaTallocatedusingnewppuubblliicc:SSaaffee():pp(nneewwTT){}SSaaffee(){ddeelleetteepp;}SSaaffee&ooppeerraattoorr=(ccoonnssttSSaaffee&aa){*pp=*aa.
pp;rreettuurrnn*tthhiiss;}//.
.
.
};tteemmppllaatteeccllaassssUUnnssaaffee{//sloppyanddangerouscodeTT*pp;//ppointstoaTppuubblliicc:UUnnssaaffee(TT*pppp):pp(pppp){}UUnnssaaffee(){iiff(!
pp->ddeessttrruuccttiibbllee())tthhrroowwEE();ddeelleetteepp;}TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
938Standard-LibraryExceptionSafetyAppendixEUUnnssaaffee&ooppeerraattoorr=(ccoonnssttUUnnssaaffee&aa){pp->TT();//destroyoldvalue(§10.
4.
11)nneeww(pp)TT(aa.
pp);//constructcopyofa.
pin*p(§10.
4.
11)rreettuurrnn*tthhiiss;}//.
.
.
};vvooiiddff(vveeccttoorr>&vvgg,vveeccttoorr>&vvbb){vvgg.
aatt(11)=SSaaffee();vvbb.
aatt(11)=UUnnssaaffee(nneewwSSoommee__ttyyppee);//.
.
.
}Inthisexample,constructionofaSSaaffeesucceedsonlyifaTTissuccessfullyconstructed.
Thecon-structionofaTTcanfailbecauseallocationmightfail(andthrowssttdd::bbaadd__aalllloocc)andbecauseTT'sconstructormightthrowanexception.
However,ineverysuccessfullyconstructedSSaaffee,ppwillpointtoasuccessfullyconstructedTT;ifaconstructorfails,noTTobject(orSSaaffeeobject)iscreated.
Similarly,TT'sassignmentoperatormaythrowanexception,causingSSaaffee'sassignmentoperatortoimplicitlyre-throwthatexception.
However,thatisnoproblemaslongasTT'sassignmentoperatoralwaysleavesitsoperandsinagoodstate.
Therefore,SSaaffeeiswellbehaved,andconsequentlyeverystandard-libraryoperationonaSSaaffeewillhaveareasonableandwell-definedresult.
Ontheotherhand,UUnnssaaffee()iscarelesslywritten(orrather,itiscarefullywrittentodemon-strateundesirablebehavior).
TheconstructionofanUUnnssaaffeewillnotfail.
Instead,theoperationsonUUnnssaaffee,suchasassignmentanddestruction,arelefttodealwithavarietyofpotentialproblems.
TheassignmentoperatormayfailbythrowinganexceptionfromTT'scopyconstructor.
ThiswouldleaveaTTinanundefinedstatebecausetheoldvalueof*ppwasdestroyedandnonewvaluereplacedit.
Ingeneral,theresultsofthatareunpredictable.
UUnnssaaffee'sdestructorcontainsanill-conceivedattempttoprotectagainstundesirabledestruction.
However,throwinganexceptiondur-ingexceptionhandlingwillcauseacalloftteerrmmiinnaattee()(§14.
7),andthestandardlibraryrequiresthatadestructorreturnnormallyafterdestroyinganobject.
Thestandardlibrarydoesnot–andcannot–makeanyguaranteeswhenausersuppliesobjectsthisbadlybehaved.
Fromthepointofviewofexceptionhandling,SSaaffeeandUUnnssaaffeedifferinthatSSaaffeeusesitscon-structortoestablishaninvariant(§24.
3.
7.
1)thatallowsitsoperationstobeimplementedsimplyandsafely.
Ifthatinvariantcannotbeestablished,anexceptionisthrownbeforeaninvalidobjectisconstructed.
UUnnssaaffee,ontheotherhand,muddlesalongwithoutameaningfulinvariant,andtheindividualoperationsthrowexceptionswithoutanoverallerror-handlingstrategy.
Naturally,thisresultsinviolationsofthestandardlibrary's(reasonable)assumptionsaboutthebehavioroftypes.
Forexample,UUnnssaaffeecanleaveinvalidelementsinacontainerafterthrowinganexceptionfromTT::ooppeerraattoorr=()andmaythrowanexceptionfromitsdestructor.
Notethatthestandard-libraryguaranteesrelativetoill-behaveduser-suppliedoperationsareanalogoustothelanguageguaranteesrelativetoviolationsofthebasictypesystem.
Ifabasicoperationisnotusedaccordingtoitsspecification,theresultingbehaviorisundefined.
ForTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
2ExceptionSafety939example,ifyouthrowanexceptionfromadestructorforavveeccttoorrelement,youhavenomorerea-sontohopeforareasonableresultthanifyoudereferenceapointerinitializedtoarandomnumber:ccllaassssBBoommbb{ppuubblliicc://.
.
.
BBoommbb(){tthhrroowwTTrroouubbllee();};};vveeccttoorrbb(1100);//leadstoundefinedbehaviorvvooiiddff(){iinntt*pp=rreeiinntteerrpprreett__ccaasstt(rraanndd());//leadstoundefinedbehavior*pp=77;}Statedpositively:Ifyouobeythebasicrulesofthelanguageandthestandardlibrary,thelibrarywillbehavewellevenwhenyouthrowexceptions.
Inadditiontoachievingpureexceptionsafety,weusuallyprefertoavoidresourceleaks.
Thatis,anoperationthatthrowsanexceptionshouldnotonlyleaveitsoperandsinwell-definedstatesbutalsoensurethateveryresourcethatitacquiredis(eventually)released.
Forexample,atthepointwhereanexceptionisthrown,allmemoryallocatedmustbeeitherdeallocatedorownedbysomeobject,whichinturnmustensurethatthememoryisproperlydeallocated.
Thestandard-libraryguaranteestheabsenceofresourceleaksprovidedthatuser-suppliedopera-tionscalledbythelibraryalsoavoidresourceleaks.
Consider:vvooiiddlleeaakk(bboooollaabboorrtt){vveeccttoorrvv(1100);//noleakvveeccttoorr*pp=nneewwvveeccttoorr(1100);//potentialmemoryleakaauuttoo__ppttrr>qq(nneewwvveeccttoorr(1100));//noleak(§14.
4.
2)iiff(aabboorrtt)tthhrroowwUUpp();//.
.
.
ddeelleetteepp;}Uponthrowingtheexception,thevveeccttoorrcalledvvandthevveeccttoorrheldbyqqwillbecorrectlydestroyedsothattheirresourcesarereleased.
Thevveeccttoorrpointedtobyppisnotguardedagainstexceptionsandwillnotbedestroyed.
Tomakethispieceofcodesafe,wemusteitherexplicitlydeleteppbeforethrowingtheexceptionormakesureitisownedbyanobject–suchasanaauuttoo__ppttrr(§14.
4.
2)–thatwillproperlydestroyitifanexceptionisthrown.
Notethatthelanguagerulesforpartialconstructionanddestructionensurethatexceptionsthrownwhileconstructingsub-objectsandmemberswillbehandledcorrectlywithoutspecialatten-tionfromstandard-librarycode(§14.
4.
1).
Thisruleisanessentialunderpinningforalltechniquesdealingwithexceptions.
Also,rememberthatmemoryisn'ttheonlykindofresourcethatcanleak.
Openedfiles,locks,networkconnections,andthreadsareexamplesofsystemresourcesthatafunctionmayhavetoreleaseorhandovertoanobjectbeforethrowinganexception.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
940Standard-LibraryExceptionSafetyAppendixEE.
3Exception-SafeImplementationTechniquesAsusual,thestandardlibraryprovidesexamplesofproblemsthatoccurinmanyothercontextsandofsolutionsthatapplywidely.
Thebasictoolsavailableforwritingexception-safecodeare[1]thetry-block(§8.
3.
1),and[2]thesupportforthe''resourceacquisitionisinitialization''technique(§14.
4).
Thegeneralprinciplestofollowareto[3]neverletgoofapieceofinformationbeforewecanstoreitsreplacement,and[4]alwaysleaveobjectsinvalidstateswhenthrowingorre-throwinganexception.
Thatway,wecanalwaysbackoutofanerrorsituation.
Thepracticaldifficultyinfollowingtheseprinciplesisthatinnocent-lookingoperations(suchas>ccllaassssvveeccttoorr{pprriivvaattee:TT*vv;//startofallocationTT*ssppaaccee;//endofelementsequence,startofspaceallocatedforpossibleexpansionTT*llaasstt;//endofallocatedspaceAAaalllloocc;//allocatorTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
3.
1ASimpleVector941ppuubblliicc:eexxpplliicciittvveeccttoorr(ssiizzee__ttyyppeenn,ccoonnssttTT&vvaall=TT(),ccoonnssttAA&=AA());vveeccttoorr(ccoonnssttvveeccttoorr&aa);//copyconstructorvveeccttoorr&ooppeerraattoorr=(ccoonnssttvveeccttoorr&aa);//copyassignmentvveeccttoorr();ssiizzee__ttyyppeessiizzee()ccoonnsstt{rreettuurrnnssppaaccee-vv;}ssiizzee__ttyyppeeccaappaacciittyy()ccoonnsstt{rreettuurrnnllaasstt-vv;}vvooiiddppuusshh__bbaacckk(ccoonnssttTT&);//.
.
.
};Considerfirstanaiveimplementationofaconstructor:tteemmppllaatteevveeccttoorr::vveeccttoorr(ssiizzee__ttyyppeenn,ccoonnssttTT&vvaall,ccoonnssttAA&aa)//warning:naiveimplementation:aalllloocc(aa)//copytheallocator{vv=aalllloocc.
aallllooccaattee(nn);//getmemoryforelements(§19.
4.
1)ssppaaccee=llaasstt=vv+nn;ffoorr(TT*pp=vv;pp!
=llaasstt;++pp)aa.
ccoonnssttrruucctt(pp,vvaall);//constructcopyofvalin*p(§19.
4.
1)}Therearethreesourcesofexceptionshere:[1]aallllooccaattee()throwsanexceptionindicatingthatnomemoryisavailable;[2]theallocator'scopyconstructorthrowsanexception;[3]thecopyconstructorfortheelementtypeTTthrowsanexceptionbecauseitcan'tcopyvvaall.
Inallcases,noobjectiscreated,sovveeccttoorr'sdestructorisnotcalled(§14.
4.
1).
Whenaallllooccaattee()fails,thetthhrroowwwillexitbeforeanyresourcesareacquired,soalliswell.
WhenTT'scopyconstructorfails,wehaveacquiredsomememorythatmustbefreedtoavoidmemoryleaks.
AmoredifficultproblemisthatthecopyconstructorforTTmightthrowanexcep-tionaftercorrectlyconstructingafewelementsbutbeforeconstructingthemall.
Tohandlethisproblem,wecouldkeeptrackofwhichelementshavebeenconstructedanddestroythose(andonlythose)incaseofanerror:tteemmppllaatteevveeccttoorr::vveeccttoorr(ssiizzee__ttyyppeenn,ccoonnssttTT&vvaall,ccoonnssttAA&aa)//elaborateimplementation:aalllloocc(aa)//copytheallocator{vv=aalllloocc.
aallllooccaattee(nn);//getmemoryforelementsiitteerraattoorrpp;ttrryy{iitteerraattoorreenndd=vv+nn;ffoorr(pp=vv;pp!
=eenndd;++pp)aalllloocc.
ccoonnssttrruucctt(pp,vvaall);//constructelement(§19.
4.
1)llaasstt=ssppaaccee=pp;}TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
942Standard-LibraryExceptionSafetyAppendixEccaattcchh(.
.
.
){ffoorr(iitteerraattoorrqq=vv;qq!
=pp;++qq)aalllloocc.
ddeessttrrooyy(qq);//destroyconstructedelementsaalllloocc.
ddeeaallllooccaattee(vv,nn);//freememorytthhrrooww;//re-throw}}Theoverheadhereistheoverheadofthetry-block.
InagoodC++implementation,thisoverheadisnegligiblecomparedtothecostofallocatingmemoryandinitializingelements.
Forimplementa-tionswhereenteringatry-blockincursacost,itmaybeworthwhiletoaddatestiiff(nn)beforethettrryyandhandletheemptyvectorcaseseparately.
Themainpartofthisconstructorisanexception-safeimplementationofuunniinniittiiaalliizzeedd__ffiillll():tteemmppllaatteevvooiidduunniinniittiiaalliizzeedd__ffiillll(FFoorrbbeegg,FFoorreenndd,ccoonnssttTT&xx){FFoorrpp;ttrryy{ffoorr(pp=bbeegg;pp!
=eenndd;++pp)nneeww(ssttaattiicc__ccaasstt(&*pp))TT(xx);//constructcopyofxin*p(§10.
4.
11)}ccaattcchhdestroyconstructedelementsandrethrow:ffoorr(FFoorrqq=bbeegg;qq!
=pp;++qq)(&*qq)->TT(10.
4.
11)tthhrrooww;}}Thecuriousconstruct&*pptakescareofiteratorsthatarenotpointers.
Inthatcase,weneedtotaketheaddressoftheelementobtainedbydereferencetogetapointer.
Theexplicitcasttovvooiidd*ensuresthatthestandardlibraryplacementfunctionisused(§19.
4.
5),andnotsomeuser-definedooppeerraattoorrnneeww()forTT*s.
Thiscodeisoperatingataratherlowlevelwherewritingtrulygeneralcodecanbedifficult.
Fortunately,wedon'thavetoreimplementuunniinniittiiaalliizzeedd__ffiillll(),becausethestandardlibraryprovidesthedesiredstrongguaranteeforit(§E.
2).
Itisoftenessentialtohaveinitializationopera-tionsthateithercompletesuccessfully,havinginitializedeveryelement,orfailleavingnocon-structedelementsbehind.
Consequently,thestandard-libraryalgorithmsuunniinniittiiaalliizzeedd__ffiillll(),uunniinniittiiaalliizzeedd__ffiillll__nn(),anduunniinniittiiaalliizzeedd__ccooppyy()(§19.
4.
4)areguaranteedtohavethisstrongexception-safetyproperty(§E.
4.
4).
Notethattheuunniinniittiiaalliizzeedd__ffiillll()algorithmdoesnotprotectagainstexceptionsthrownbyele-mentdestructorsoriteratoroperations(§E.
4.
4).
Doingsowouldbeprohibitivelyexpensive(see§E.
8[16-17]).
Theuunniinniittiiaalliizzeedd__ffiillll()algorithmcanbeappliedtomanykindsofsequences.
Consequently,ittakesaforwarditerator(§19.
2.
1)andcannotguaranteetodestroyelementsinthereverseorderoftheirconstruction.
Usinguunniinniittiiaalliizzeedd__ffiillll(),wecanwrite:TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
3.
1ASimpleVector943tteemmppllaatteevveeccttoorr::vveeccttoorr(ssiizzee__ttyyppeenn,ccoonnssttTT&vvaall,ccoonnssttAA&aa)//messyimplementation:aalllloocc(aa)//copytheallocator{vv=aalllloocc.
aallllooccaattee(nn);//getmemoryforelementsttrryy{uunniinniittiiaalliizzeedd__ffiillll(vv,vv+nn,vvaall);//copyelementsssppaaccee=llaasstt=vv+nn;}ccaattcchh(.
.
.
){aalllloocc.
ddeeaallllooccaattee(vv,nn);//freememorytthhrrooww;//re-throw}}However,Iwouldn'tcallthatprettycode.
Thenextsectionwilldemonstratehowitcanbemademuchsimpler.
Notethattheconstructorre-throwsacaughtexception.
Theintentistomakevveeccttoorrtransparenttoexceptionssothattheusercandeterminetheexactcauseofaproblem.
Allstandard-librarycon-tainershavethisproperty.
Exceptiontransparencyisoftenthebestpolicyfortemplatesandother''thin''layersofsoftware.
Thisisincontrasttomajorpartsofasystem(''modules'')thatgener-allyneedtotakeresponsibilityforallexceptionsthrown.
Thatis,theimplementerofsuchamod-ulemustbeabletolisteveryexceptionthatthemodulecanthrow.
Achievingthismayinvolvegroupingexceptions(§14.
2),mappingexceptionsfromlower-levelroutinesintothemodule'sownexceptions(§14.
6.
3),orexceptionspecification(§14.
6).
E.
3.
2RepresentingMemoryExplicitlyExperiencerevealedthatwritingcorrectexception-safecodeusingexplicittry-blocksismorediffi-cultthanmostpeopleexpect.
Infact,itisunnecessarilydifficultbecausethereisanalternative:The''resourceacquisitionisinitialization''technique(§14.
4)canbeusedtoreducetheamountofcodeneedingtobewrittenandtomakethecodemorestylized.
Inthiscase,thekeyresourcerequiredbythevveeccttoorrismemorytoholditselements.
Byprovidinganauxiliaryclasstorepresentthenotionofmemoryusedbyavveeccttoorr,wecansimplifythecodeanddecreasethechanceofacci-dentallyforgettingtoreleaseit:tteemmppllaattee>ssttrruuccttvveeccttoorr__bbaassee{AAaalllloocc;//allocatorTT*vv;//startofallocationTT*ssppaaccee;//endofelementsequence,startofspaceallocatedforpossibleexpansionTT*llaasstt;//endofallocatedspacevveeccttoorr__bbaassee(ccoonnssttAA&aa,ttyyppeennaammeeAA::ssiizzee__ttyyppeenn):aalllloocc(aa),vv(aa.
aallllooccaattee(nn)),ssppaaccee(vv+nn),llaasstt(vv+nn){}vveeccttoorr__bbaassee(){aalllloocc.
ddeeaallllooccaattee(vv,llaasstt-vv);}};Aslongasvvandllaassttarecorrect,vveeccttoorr__bbaasseecanbedestroyed.
Classvveeccttoorr__bbaasseedealswithTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
944Standard-LibraryExceptionSafetyAppendixEmemoryforatypeTT,notobjectsoftypeTT.
Consequently,auserofvveeccttoorr__bbaasseemustdestroyallconstructedobjectsinavveeccttoorr__bbaasseebeforethevveeccttoorr__bbaasseeitselfisdestroyed.
Naturally,vveeccttoorr__bbaasseeitselfiswrittensothatifanexceptionisthrown(bytheallocator'scopyconstructororaallllooccaattee()function)novveeccttoorr__bbaasseeobjectiscreatedandnomemoryisleaked.
Wewanttobeabletosswwaapp()vveeccttoorr__bbaassees.
However,thedefaultsswwaapp()doesn'tsuitourneedsbecauseitcopiesanddestroysatemporary.
Becausevveeccttoorr__bbaasseeisaspecial-purposeclassthatwasn'tgivenfool-proofcopysemantics,thatdestructionswouldleadtoundesirablesideef-fects.
Consequently,weprovideaspecialization:tteemmppllaatteevvooiiddsswwaapp(vveeccttoorr__bbaassee&aa,vveeccttoorr__bbaassee&bb){sswwaapp(aa.
aa,bb.
aa);sswwaapp(aa.
vv,bb.
vv);sswwaapp(aa.
ssppaaccee,bb.
ssppaaccee);sswwaapp(aa.
llaasstt,bb.
llaasstt);}Givenvveeccttoorr__bbaassee,vveeccttoorrcanbedefinedlikethis:tteemmppllaattee>ccllaassssvveeccttoorr:pprriivvaatteevveeccttoorr__bbaassee{vvooiiddddeessttrrooyy__eelleemmeennttss(){ffoorr(TT*pp=vv;pp!
=ssppaaccee;++pp)pp->TT(10.
4.
11ppuubblliicc:eexxpplliicciittvveeccttoorr(ssiizzee__ttyyppeenn,ccoonnssttTT&vvaall=TT(),ccoonnssttAA&=AA());vveeccttoorr(ccoonnssttvveeccttoorr&aa);//copyconstructorvveeccttoorr&ooppeerraattoorr=(ccoonnssttvveeccttoorr&aa);//copyassignmentvveeccttoorr(){ddeessttrrooyy__eelleemmeennttss();}ssiizzee__ttyyppeessiizzee()ccoonnsstt{rreettuurrnnssppaaccee-vv;}ssiizzee__ttyyppeeccaappaacciittyy()ccoonnsstt{rreettuurrnnllaasstt-vv;}vvooiiddppuusshh__bbaacckk(ccoonnssttTT&);//.
.
.
};ThevveeccttoorrdestructorexplicitlyinvokestheTTdestructorforeveryelement.
Thisimpliesthatifanelementdestructorthrowsanexception,thevveeccttoorrdestructionfails.
Thiscanbeadisasterifithap-pensduringstackunwindingcausedbyanexceptionandtteerrmmiinnaattee()iscalled(§14.
7).
Inthecaseofnormaldestruction,throwinganexceptionfromadestructortypicallyleadstoresourceleaksandunpredictablebehaviorofcoderelyingonreasonablebehaviorofobjects.
Thereisnoreallygoodwaytoprotectagainstexceptionsthrownfromdestructors,sothelibrarymakesnoguaranteesifanelementdestructorthrows(§E.
4).
Nowtheconstructorcanbesimplydefined:tteemmppllaatteevveeccttoorr::vveeccttoorr(ssiizzee__ttyyppeenn,ccoonnssttTT&vvaall,ccoonnssttAA&aa):vveeccttoorr__bbaassee(aa,nn)//allocatespacefornelements{uunniinniittiiaalliizzeedd__ffiillll(vv,vv+nn,vvaall);//copyelements}Thecopyconstructordiffersbyusinguunniinniittiiaalliizzeedd__ccooppyy()insteadofuunniinniittiiaalliizzeedd__ffiillll():TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
3.
2RepresentingMemoryExplicitly945tteemmppllaatteevveeccttoorr::vveeccttoorr(ccoonnssttvveeccttoorr&aa):vveeccttoorr__bbaassee(aa.
aalllloocc,aa.
ssiizzee()){uunniinniittiiaalliizzeedd__ccooppyy(aa.
bbeeggiinn(),aa.
eenndd(),vv);}Notethatthisstyleofconstructorreliesonthefundamentallanguagerulethatwhenanexceptionisthrownfromaconstructor,sub-objects(suchasbases)thathavealreadybeencompletelycon-structedwillbeproperlydestroyed(§14.
4.
1).
Theuunniinniittiiaalliizzeedd__ffiillll()algorithmanditscousins(§E.
4.
4)providetheequivalentguaranteeforpartiallyconstructedsequences.
E.
3.
3AssignmentAsusual,assignmentdiffersfromconstructioninthatanoldvaluemustbetakencareof.
Considerastraightforwardimplementation:tteemmppllaatteevveeccttoorr&vveeccttoorr::ooppeerraattoorr=(ccoonnssttvveeccttoorr&aa)//offersthestrongguarantee(§E.
2){vveeccttoorr__bbaasseebb(aalllloocc,aa.
ssiizzee());//getmemoryuunniinniittiiaalliizzeedd__ccooppyy(aa.
bbeeggiinn(),aa.
eenndd(),bb.
vv);//copyelementsddeessttrrooyy__eelleemmeennttss();aalllloocc.
ddeeaallllooccaattee(vv,llaasstt-vv);//freeoldmemoryvveeccttoorr__bbaassee::ooppeerraattoorr=(bb);//installnewrepresentationbb.
vv=00;//preventdeallocationrreettuurrnn*tthhiiss;}Thisassignmentissafe,butitrepeatsalotofcodefromconstructorsanddestructors.
Toavoidthis,wecouldwrite:tteemmppllaatteevveeccttoorr&vveeccttoorr::ooppeerraattoorr=(ccoonnssttvveeccttoorr&aa)//offersthestrongguarantee(§E.
2){vveeccttoorrtteemmpp(aa);//copyasswwaapp>(*tthhiiss,tteemmpp);//swaprepresentationsrreettuurrnn*tthhiiss;}Theoldelementsaredestroyedbytteemmpp'sdestructor,andthememoryusedtoholdthemisdeallo-catedbytteemmpp'svveeccttoorr__bbaassee'sdestructor.
Theperformanceofthetwoversionsoughttobeequivalent.
Essentially,theyarejusttwodif-ferentwaysofspecifyingthesamesetofoperations.
However,thesecondimplementationisshorteranddoesn'treplicatecodefromrelatedvveeccttoorrfunctions,sowritingtheassignmentthatwayoughttobelesserrorproneandleadtosimplermaintenance.
Notetheabsenceofthetraditionaltestforself-assignment(§10.
4.
4).
Theseassignmentimple-mentationsworkbyfirstconstructingacopyandthenswappingrepresentations.
Thisobviouslyhandlesself-assignmentcorrectly.
IdecidedthattheefficiencygainedfromthetestintherarecaseTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
946Standard-LibraryExceptionSafetyAppendixEofself-assignmentwasmorethanoffsetbyitscostinthecommoncasewhereadifferentvveeccttoorrisassigned.
Ineithercase,twopotentiallysignificantoptimizationsaremissing:[1]Ifthecapacityofthevectorassignedtoislargeenoughtoholdtheassignedvector,wedon'tneedtoallocatenewmemory.
[2]Anelementassignmentmaybemoreefficientthananelementdestructionfollowedbyanelementconstruction.
Implementingtheseoptimizations,weget:tteemmppllaatteevveeccttoorr&vveeccttoorr::ooppeerraattoorr=(ccoonnssttvveeccttoorr&aa)//optimized,basicguarantee(§E.
2){iiff(ccaappaacciittyy()>(*tthhiiss,tteemmpp);//swaprepresentationsrreettuurrnn*tthhiiss;}iiff(tthhiiss==&aa)rreettuurrnn*tthhiiss;//protectagainstselfassignment(§10.
4.
4)//assigntooldelements:ssiizzee__ttyyppeesszz=ssiizzee();ssiizzee__ttyyppeeaasszz=aa.
ssiizzee();aalllloocc=aa.
ggeett__aallllooccaattoorr();//copytheallocatoriiff(aasszzTT();//destroysurpluselements(§10.
4.
11)}eellssee{ccooppyy(aa.
bbeeggiinn(),aa.
bbeeggiinn()+sszz,vv);uunniinniittiiaalliizzeedd__ccooppyy(aa.
bbeeggiinn()+sszz,aa.
eenndd(),ssppaaccee);//constructextraelements}ssppaaccee=vv+aasszz;rreettuurrnn*tthhiiss;}Theseoptimizationsarenotfree.
Theccooppyy()algorithm(§18.
6.
1)doesnotofferthestrongexception-safetyguarantee.
Itdoesnotguaranteethatitwillleaveitstargetunchangedifanexcep-tionisthrownduringcopying.
Thus,ifTT::ooppeerraattoorr=()throwsanexceptionduringccooppyy(),thevveeccttoorrbeingassignedtoneednotbeacopyofthevectorbeingassigned,anditneednotbeunchanged.
Forexample,thefirstfiveelementsmightbecopiesofelementsoftheassignedvectorandtherestunchanged.
Itisalsoplausiblethatanelement–theelementthatwasbeingcopiedwhenTT::ooppeerraattoorr=()threwanexception–endsupwithavaluethatisneithertheoldvaluenoracopyofthecorrespondingelementinthevectorbeingassigned.
However,ifTT::ooppeerraattoorr=()leavesitsoperandsinavalidstateifitthrowsanexception,thevveeccttoorrisstillinavalidstate–evenifitwasn'tthestatewewouldhavepreferred.
Here,Ihavecopiedtheallocatorusinganassignment.
Itisactuallynotrequiredthateveryallo-catorsupportassignment(§19.
4.
3);seealso§E.
8[9].
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
3.
3Assignment947Thestandard-libraryvveeccttoorrassignmentofferstheweakerexception-safetypropertyofthislastimplementation–anditspotentialperformanceadvantages.
Thatis,vveeccttoorrassignmentprovidesthebasicguarantee,soitmeetsmostpeople'sideaofexceptionsafety.
However,itdoesnotpro-videthestrongguarantee(§E.
2).
Ifyouneedanassignmentthatleavesthevveeccttoorrunchangedifanexceptionisthrown,youmusteitherusealibraryimplementationthatprovidesthestrongguaran-teeorprovideyourownassignmentoperation.
Forexample:tteemmppllaatteevvooiiddssaaffee__aassssiiggnn(vveeccttoorr&aa,ccoonnssttvveeccttoorr&bb)//"obvious"a=b{vveeccttoorrtteemmpp(aa.
ggeett__aallllooccaattoorr());tteemmpp.
rreesseerrvvee(bb.
ssiizzee());ffoorr(ttyyppeennaammeevveeccttoorr::iitteerraattoorrpp=bb.
bbeeggiinn();pp!
=bb.
eenndd();++pp)tteemmpp.
ppuusshh__bbaacckk(*pp);sswwaapp(aa,tteemmpp);}Ifthereisinsufficientmemoryfortteemmpptobecreatedwithroomforbb.
ssiizzee()elements,ssttdd::bbaadd__aallllooccisthrownbeforeanychangesaremadetoaa.
Similarly,ifppuusshh__bbaacckk()failsforanyreason,aawillremainuntouchedbecauseweapplyppuusshh__bbaacckk()totteemmppratherthantoaa.
Inthatcase,anyelementsoftteemmppcreatedbyppuusshh__bbaacckk()willbedestroyedbeforetheexceptionthatcausedthefailureisre-thrown.
Swapdoesnotcopyvveeccttoorrelements.
Itsimplyswapsthedatamembersofavveeccttoorr;thatis,itswapsvveeccttoorr__bbaassees(§E.
3.
2).
Consequently,itdoesnotthrowexceptionsevenifoperationsontheelementsmight(§E.
4.
3).
Consequently,ssaaffee__aassssiiggnn()doesnotdospuriouscopiesofelementsandisreasonablyefficient.
Asisoftenthecase,therearealternativestotheobviousimplementation.
Wecanletthelibraryperformthecopyintothetemporaryforus:tteemmppllaatteevvooiiddssaaffee__aassssiiggnn(vveeccttoorr&aa,ccoonnssttvveeccttoorr&bb)//simplea=b{vveeccttoorrtteemmpp(bb);//copytheelementsofbintoatemporarysswwaapp(aa,tteemmpp);}Indeed,wecouldsimplyusecall-by-value(§7.
2):tteemmppllaatteevvooiiddssaaffee__aassssiiggnn(vveeccttoorr&aa,vveeccttoorrbb)//simplea=b(note:bispassedbyvalue){sswwaapp(aa,bb);}E.
3.
4ppuusshh__bbaacckk(())Fromanexception-safetypointofview,ppuusshh__bbaacckk()issimilartotheassignmentinthatwemusttakecarethatthevveeccttoorrremainsunchangedifwefailtoaddanewelement:TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
948Standard-LibraryExceptionSafetyAppendixEtteemmppllaatteevvooiiddvveeccttoorr::ppuusshh__bbaacckk(ccoonnssttTT&xx){iiff(ssppaaccee==llaasstt){//nomorefreespace;relocate:vveeccttoorr__bbaasseebb(aalllloocc,ssiizzee()22*ssiizzee():22);//doubletheallocationuunniinniittiiaalliizzeedd__ccooppyy(vv,ssppaaccee,bb.
vv);nneeww(bb.
ssppaaccee)TT(xx);//placeacopyofxin*b.
space(§10.
4.
11)++bb.
ssppaaccee;ddeessttrrooyy__eelleemmeennttss();sswwaapp>(bb,*tthhiiss);//swaprepresentationsrreettuurrnn;}nneeww(ssppaaccee)TT(xx);//placeacopyofxin*space(§10.
4.
11)++ssppaaccee;}Naturally,thecopyconstructorusedtoinitialize*ssppaacceemightthrowanexception.
Ifthathappens,thevalueofthevveeccttoorrremainsunchanged,withssppaacceeleftunincremented.
Inthatcase,thevveeccttoorrelementsarenotreallocatedsothatiteratorsreferringtothemarenotinvalidated.
Thus,thisimple-mentationimplementsthestrongguaranteethatanexceptionthrownbyanallocatororevenauser-suppliedcopyconstructorleavesthevveeccttoorrunchanged.
Thestandardlibraryoffersthatguar-anteeforppuusshh__bbaacckk()(§E.
4.
1).
Notetheabsenceofatry-block(exceptfortheonehiddeninuunniinniittiiaalliizzeedd__ccooppyy()).
Theupdatewasdonebycarefullyorderingtheoperationssothatifanexceptionisthrown,thevveeccttoorrremainsunchanged.
Theapproachofgainingexceptionsafetythroughorderingandthe''resourceacquisitionisinitialization''technique(§14.
4)tendstobemoreelegantandmoreefficientthanexplicitlyhan-dlingerrorsusingtry-blocks.
Moreproblemswithexceptionsafetyarisefromaprogrammerorder-ingcodeinunfortunatewaysthanfromlackofspecificexception-handlingcode.
Thebasicruleoforderingisnottodestroyinformationbeforeitsreplacementhasbeenconstructedandcanbeassignedwithoutthepossibilityofanexception.
Exceptionsintroducepossibilitiesforsurprisesintheformofunexpectedcontrolflows.
Forapieceofcodewithasimplelocalcontrolflow,suchastheooppeerraattoorr=(),ssaaffee__aassssiiggnn(),andppuusshh__bbaacckk()examples,theopportunitiesforsurprisesarelimited.
Itisrelativelysimpletolookatsuchcodeandaskoneself''canthislineofcodethrowanexception,andwhathappensifitdoes''Forlargefunctionswithcomplicatedcontrolstructures,suchascomplicatedconditionalstatementsandnestedloops,thiscanbehard.
Addingtry-blocksincreasesthislocalcontrolstructurecom-plexityandcanthereforebeasourceofconfusionanderrors(§14.
4).
Iconjecturethattheeffec-tivenessoftheorderingapproachandthe''resourceacquisitionisinitialization''approachcom-paredtomoreextensiveuseoftry-blocksstemsfromthesimplificationofthelocalcontrolflow.
Simple,stylizedcodeiseasiertounderstandandeasiertogetright.
Notethatthevveeccttoorrimplementationispresentedasanexampleoftheproblemsthatexceptionscanposeandoftechniquesforaddressingthoseproblems.
Thestandarddoesnotrequireanimple-mentationtobeexactlyliketheonepresentedhere.
Whatthestandarddoesguaranteeisthesub-jectof§E.
4.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
3.
5ConstructorsandInvariants949E.
3.
5ConstructorsandInvariantsFromthepointofviewofexceptionsafety,othervveeccttoorroperationsareeitherequivalenttotheonesalreadyexamined(becausetheyacquireandreleaseresourcesinsimilarways)ortrivial(becausetheydon'tperformoperationsthatrequireclevernesstomaintainvalidstates).
However,formostclasses,such''trivial''functionsconstitutethemajorityofcode.
Thedifficultyofwritingsuchfunctionsdependscriticallyontheenvironmentthataconstructorestablishedforthemtooperatein.
Saiddifferently,thecomplexityof''ordinarymemberfunctions''dependscriticallyonchoos-ingagoodclassinvariant(§24.
3.
7.
1).
Byexaminingthe''trivial''vveeccttoorrfunctions,itispossibletogaininsightintotheinterestingquestionofwhatmakesagoodinvariantforaclassandhowcon-structorsshouldbewrittentoestablishsuchinvariants.
Operationssuchasvveeccttoorrsubscripting(§16.
3.
3)areeasytowritebecausetheycanrelyontheinvariantestablishedbytheconstructorsandmaintainedbyallfunctionsthatacquireorreleaseresources.
Inparticular,asubscriptoperatorcanrelyonvvreferringtoanarrayofelements:tteemmppllaatteeTT&vveeccttoorr::ooppeerraattoorr[](ssiizzee__ttyyppeeii){rreettuurrnnvv[ii];}Itisimportantandfundamentaltohaveconstructorsacquireresourcesandestablishasimpleinvariant.
Toseewhy,consideranalternativedefinitionofvveeccttoorr__bbaassee:tteemmppllaattee>//clumsyuseofconstructorccllaassssvveeccttoorr__bbaassee{ppuubblliicc:AAaalllloocc;//allocatorTT*vv;//startofallocationTT*ssppaaccee;//endofelementsequence,startofspaceallocatedforpossibleexpansionTT*llaasstt;//endofallocatedspacevveeccttoorr__bbaassee(ccoonnssttAA&aa,ttyyppeennaammeeAA::ssiizzee__ttyyppeenn):aalllloocc(aa),vv(00),ssppaaccee(00),llaasstt(00){vv=aalllloocc.
aallllooccaattee(nn);ssppaaccee=llaasstt=vv+nn;}vveeccttoorr__bbaassee(){iiff(vv)aalllloocc.
ddeeaallllooccaattee(vv,llaasstt-vv);}};Here,Iconstructavveeccttoorr__bbaasseeintwostages:First,Iestablisha''safestate''wherevv,ssppaaccee,andllaassttaresetto00.
OnlyafterthathasbeendonedoItrytoallocatememory.
Thisisdoneoutofmisplacedfearthatifanexceptionhappensduringelementallocation,apartiallyconstructedobjectcouldbeleftbehind.
Thisfearismisplacedbecauseapartiallyconstructedobjectcannotbe''leftbehind''andlateraccessed.
Therulesforstaticobjects,automaticobjects,memberobjects,andelementsofthestandard-librarycontainerspreventthat.
However,itcould/canhappeninpre-standardlibrariesthatused/useplacementnew(§10.
4.
11)toconstructobjectsincontainersdesignedwithoutconcernforexceptionsafety.
Oldhabitscanbehardtobreak.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
950Standard-LibraryExceptionSafetyAppendixENotethatthisattempttowritesafercodecomplicatestheinvariantfortheclass:Itisnolongerguaranteedthatvvpointstoallocatedmemory.
Nowvvmightbe00.
Thishasoneimmediatecost.
Thestandard-libraryrequirementsforallocatorsdonotguaranteethatwecansafelydeallocateapointerwiththevalue00(§19.
4.
1).
Inthis,allocatorsdifferfromddeelleettee(§6.
2.
6).
Consequently,Ihadtoaddatestinthedestructor.
Also,eachelementisfirstinitializedandthenassigned.
Thecostofdoingthatextraworkcanbesignificantforelementtypesforwhichassignmentisnontriv-ial,suchasssttrriinnggandlliisstt.
Thistwo-stageconstructisnotanuncommonstyle.
Sometimes,itisevenmadeexplicitbyhavingtheconstructordoonlysome''simpleandsafe''initializationtoputtheobjectintoadestructiblestate.
Therealconstructionislefttoaniinniitt()functionthattheusermustexplicitlycall.
Forexample:tteemmppllaattee//archaic(pre-standard,pre-exception)styleccllaassssvveeccttoorr__bbaassee{ppuubblliicc:TT*vv;//startofallocationTT*ssppaaccee;//endofelementsequence,startofspaceallocatedforpossibleexpansionTT*llaasstt;//endofallocatedspacevveeccttoorr__bbaassee():vv(00),ssppaaccee(00),llaasstt(00){}vveeccttoorr__bbaassee(){ffrreeee(vv);}bboooolliinniitt(ssiizzee__ttnn)//returntrueifinitializationsucceeded{iiff(vv=(TT*)mmaalllloocc(ssiizzeeooff(TT)*nn)){uunniinniittiiaalliizzeedd__ffiillll(vv,vv+nn,TT());ssppaaccee=llaasstt=vv+nn;rreettuurrnnttrruuee;}rreettuurrnnffaallssee;}};Theperceivedvalueofthisstyleis[1]Theconstructorcan'tthrowanexception,andthesuccessofaninitializationusingiinniitt()canbetestedby''usual''(thatis,non-exception)means.
[2]Thereexistsatrivialvalidstate.
Incaseofaseriousproblem,anoperationcangiveanobjectthatstate.
[3]Theacquisitionofresourcesisdelayeduntilafullyinitializedobjectisactuallyneeded.
Thefollowingsubsectionsexaminethesepointsandshowswhythistwo-stageconstructiontech-niquedoesn'tdeliveritsexpectedbenefits.
Itcanalsobeasourceofproblems.
E.
3.
5.
1Usingiinniitt(())FunctionsThefirstpoint(usinganiinniitt()functioninpreferencetoaconstructor)isbogus.
Usingconstruc-torsandexceptionhandlingisamoregeneralandsystematicwayofdealingwithresourceacquisi-tionandinitializationerrors(§14.
1,§14.
4).
Thisstyleisarelicofpre-exceptionC++.
Carefullywrittencodeusingthetwostylesareroughlyequivalent.
Consider:TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
3.
5.
1Usingiinniitt(())Functions951iinnttff11(iinnttnn){vveeccttoorrvv;//.
.
.
iiff(vv.
iinniitt(nn)){//usevasvectorofnelements}eellssee{//handle_problem}}andiinnttff22(iinnttnn)ttrryy{vveeccttoorrvvvv(nn);//.
.
.
//usevasvectorofnelements}ccaattcchh(.
.
.
){//handleproblem}However,havingaseparateiinniitt()functionisanopportunityto[1]forgettocalliinniitt()(§10.
2.
3),[2]forgettotestonthesuccessofiinniitt(),[3]calliinniitt()morethanonce,[4]forgetthatiinniitt()mightthrowanexception,and[5]usetheobjectbeforecallingiinniitt().
Thedefinitionofvveeccttoorr::iinniitt()illustrates[4].
InagoodC++implementation,ff22()willbemarginallyfasterthanff11()becauseitavoidsthetestinthecommoncase.
E.
3.
5.
2RelyingonaDefaultValidStateThesecondpoint(havinganeasy-to-construct''default''validstate)iscorrectingeneral,butinthecaseofvveeccttoorr,itisachievedatanunnecessarycost.
Itisnowpossibletohaveavveeccttoorr__bbaasseewithvv==00,sothevectorimplementationmustprotectagainstthatpossibilitythroughout.
Forexample:tteemmppllaatteeTT&vveeccttoorr::ooppeerraattoorr[](ssiizzee__ttii){iiff(vv)rreettuurrnnvv[ii];//handleerror}Leavingthepossibilityofvv==00openmakesthecostofnon-range-checkedsubscriptingequivalenttorange-checkedaccess:TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
952Standard-LibraryExceptionSafetyAppendixEtteemmppllaatteeTT&vveeccttoorr::aatt(ssiizzee__ttii){iiff(iivvooiiddvveeccttoorr::eemmeerrggeennccyy__eexxiitt(){ssppaaccee=vv;//setthesizeof*thisto0tthhrroowwTToottaall__ffaaiilluurree();}Thisisabitdrasticbecauseitfailstocallelementdestructorsandtodeallocatethespaceforele-mentsheldbythevveeccttoorr__bbaassee.
Thatis,itfailstoprovidethebasicguarantee(§E.
2).
Ifwearewillingtotrustthevaluesofvvandssppaacceeandtheelementdestructors,wecanavoidpotentialresourceleaks:tteemmppllaatteevvooiiddvveeccttoorr::eemmeerrggeennccyy__eexxiitt(){ddeessttrrooyy__eelleemmeennttss();//cleanuptthhrroowwTToottaall__ffaaiilluurree();}Pleasenotethatthestandardvveeccttoorrissuchacleandesignthatitminimizestheproblemscausedbytwo-phaseconstruction.
Theiinniitt()functionisroughlyequivalenttorreessiizzee(),andinmostplacesthepossibilityofvv==00isalreadycoveredbyssiizzee()==00tests.
Thenegativeeffectsdescribedfortwo-phaseconstructionbecomemoremarkedwhenweconsiderapplicationclassesthatacquiresignificantresources,suchasnetworkconnectionsandfiles.
Suchclassesarerarelypartofaframeworkthatguidestheiruseandtheirimplementationinthewaythestandard-libraryrequire-mentsguidethedefinitionanduseofvveeccttoorr.
Theproblemsalsotendtoincreaseasthemappingbetweentheapplicationconceptsandtheresourcesrequiredtoimplementthembecomesmorecomplex.
Fewclassesmapasdirectlyontosystemresourcesasdoesvveeccttoorr.
Theideaofhavinga''safestate''isinprincipleagoodone.
Ifwecan'tputanobjectintoavalidstatewithoutfearofthrowinganexceptionbeforecompletingthatoperation,wedoindeedTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
3.
5.
2RelyingonaDefaultValidState953haveaproblem.
However,this''safestate''shouldbeonethatisanaturalpartofthesemanticsoftheclassratherthananimplementationartifactthatcomplicatestheclassinvariant.
E.
3.
5.
3DelayingresourceacquisitionLikethesecondpoint(§E.
3.
5.
2),thethird(todelayacquisitionuntilaresourceisneeded)misap-pliesagoodideainawaythatimposescostwithoutyieldingbenefits.
Inmanycases,notablyincontainerssuchasvveeccttoorr,thebestwayofdelayingresourceacquisitionisfortheprogrammertodelaythecreationofobjectsuntiltheyareneeded.
Consideranaiveuseofvveeccttoorr:vvooiiddff(iinnttnn){vveeccttoorrvv(nn);//makendefaultobjectsoftypeX//.
.
.
vv[33]=XX(9999);//real''initialization''ofv[3]//.
.
.
}ConstructinganXXonlytoassignanewvaluetoitlateriswasteful–especiallyifanXXassignmentisexpensive.
Therefore,two-phaseconstructionofXXcanseemattractive.
Forexample,thetypeXXmayitselfbeavveeccttoorr,sowemightconsidertwo-phaseconstructionofvveeccttoorrtooptimizecreationofemptyvveeccttoorrs.
However,creatingdefault(empty)vectorsisalreadyefficient,socomplicatingtheimplementationwithaspecialcasefortheemptyvectorseemsfutile.
Moregenerally,thebestsolutiontospuriousinitializationisrarelytoremovecomplicatedinitializationfromtheelementconstructors.
Instead,ausercancreateelementsonlywhenneeded.
Forexample:vvooiiddff22(iinnttnn){vveeccttoorrvv;//makeemptyvector//.
.
.
vv.
ppuusshh__bbaacckk(XX(9999));//constructelementwhenneeded//.
.
.
}Tosumup:thetwo-phaseconstructionapproachleadstomorecomplicatedinvariantsandtypicallytolesselegant,moreerror-prone,andharder-to-maintaincode.
Consequently,thelanguage-supported''constructorapproach''shouldbepreferredtothe''iinniitt()-functionapproach''when-everfeasible.
Thatis,resourcesshouldbeacquiredinconstructorswheneverdelayedresourceacquisitionisn'tmandatedbytheinherentsemanticsofaclass.
E.
4StandardContainerGuaranteesIfalibraryoperationitselfthrowsanexception,itcan–anddoes–makesurethattheobjectsonwhichitoperatesareleftinawell-definedstate.
Forexample,aatt()throwingoouutt__ooff__rraannggeeforavveeccttoorr(§16.
3.
3)isnotaproblemwithexceptionsafetyforthevveeccttoorr.
Thewriterofaatt()hasnoproblemmakingsurethatavveeccttoorrisinawell-definedstatebeforethrowing.
Theproblems–forTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
954Standard-LibraryExceptionSafetyAppendixElibraryimplementers,forlibraryusers,andforpeopletryingtounderstandcode–comewhenauser-suppliedfunctionthrowsanexception.
Thestandard-librarycontainersofferthebasicguarantee(§E.
2):Thebasicinvariantsofthelibraryaremaintained,andnoresourcesareleakedaslongasusercodebehavesasrequired.
Thatis,user-suppliedoperationsshouldnotleavecontainerelementsininvalidstatesorthrowexcep-tionsfromdestructors.
By''operations,''Imeanoperationsusedbythestandard-libraryimple-mentation,suchasconstructors,assignments,destructors,andoperationsoniterators(§E.
4.
4).
Itisrelativelyeasyfortheprogrammertoensurethatsuchoperationsmeetthelibrary'sexpec-tations.
Infact,muchnaivelywrittencodeconformstothelibrary'srequirements.
Thefollowingtypesclearlymeetthestandardlibrary'srequirementsforcontainerelementtypes:[1]built-intypes–includingpointers,[2]typeswithoutuser-definedoperations,[3]classeswithoperationsthatneitherthrowexceptionsnorleaveoperandsininvalidstates,[4]classeswithdestructorsthatdon'tthrowexceptionsandforwhichitissimpletoverifythatoperationsusedbythestandardlibrary(suchasconstructors,assignments,andsswwaapp())don'tleaveoperandsininvalidstates.
Ineachcase,wemustalsomakesurethatnoresourceisleaked.
Forexample:vvooiiddff(CCiirrccllee*ppcc,TTrriiaannggllee*pptt,vveeccttoorr&vv22){vveeccttoorrvv(1100);//eithercreatevectororthrowbad_allocvv[33]=ppcc;//noexceptionthrownvv.
iinnsseerrtt(vv.
bbeeggiinn()+44,pptt);//eitherinsertptornoeffectonvvv22.
eerraassee(vv22.
bbeeggiinn()+33);//eithererasev2[3]ornoeffectonv2vv22=vv;//copyvornoeffectonv2//.
.
.
}Whenff()exits,vvwillbeproperlydestroyed,andvv22willbeinavalidstate.
Thisfragmentdoesnotindicatewhoisresponsiblefordeletingppccandpptt.
Ifff()isresponsible,itcaneithercatchexceptionsanddotherequireddeletion,orassignthepointerstolocalaauuttoo__ppttrrs.
Themoreinterestingquestionis:WhendothelibraryoperationsofferthestrongguaranteethatanoperationeithersucceedsorhasnoeffectonitsoperandsForexample:vvooiiddff(vveeccttoorr&vvxx){vvxx.
iinnsseerrtt(vvxx.
bbeeggiinn()+44,XX(77));//addelement}Ingeneral,XX'soperationsandvveeccttoorr'sallocatorcanthrowanexception.
Whatcanwesayabouttheelementsofvvxxwhenff()exitsbecauseofanexceptionThebasicguaranteeensuresthatnoresourceshavebeenleakedandthatvvxxhasasetofvalidelements.
However,exactlywhatele-mentsIsvvxxunchangedCouldadefaultXXhavebeenaddedCouldanelementhavebeenremovedbecausethatwastheonlywayforiinnsseerrtt()torecoverwhilemaintainingthebasicguaran-teeSometimes,itisnotenoughtoknowthatacontainerisinagoodstate;wealsowanttoknowexactlywhatstatethatis.
Aftercatchinganexception,wetypicallywanttoknowthattheelementsareexactlythoseweintended,orwewillhavetostarterrorrecovery.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
4.
1InsertionandRemovalofElements955E.
4.
1InsertionandRemovalofElementsInsertinganelementintoacontainerandremovingoneareobviousexamplesofoperationsthatmightleaveacontainerinanunpredictablestateifanexceptionisthrown.
Thereasonisthatinser-tionsanddeletionsinvokemanyoperationsthatmaythrowexceptions:[1]Anewvalueiscopiedintoacontainer.
[2]Anelementdeletedfrom(erasedfrom)acontainermustbedestroyed.
[3]Sometimes,memorymustbeallocatedtoholdanewelement.
[4]Sometimes,vveeccttoorrandddeeqquueeelementsmustbecopiedtonewlocations.
[5]Associativecontainerscallcomparisonfunctionsforelements.
[6]Manyinsertionsanddeletionsinvolveiteratoroperations.
Eachofthesecasescancauseanexceptiontobethrown.
Ifadestructorthrowsanexception,noguaranteesaremade(§E.
2).
Makingguaranteesinthiscasewouldbeprohibitivelyexpensive.
However,thelibrarycananddoesprotectitself–anditsusers–fromexceptionsthrownbyotheruser-suppliedoperations.
Whenmanipulatingalinkeddatastructure,suchasalliissttorammaapp,elementscanbeaddedandremovedwithoutaffectingotherelementsinthecontainer.
Thisisnotthecaseforacontainerimplementedusingcontiguousallocationofelements,suchasavveeccttoorroraddeeqquuee.
There,elementssometimesneedtobemovedtonewlocations.
Inadditiontothebasicguarantee,thestandardlibraryoffersthestrongguaranteeforafewoperationsthatinsertorremoveelements.
Becausecontainersimplementedaslinkeddatastruc-turesbehavedifferentlyfromcontainerswithcontiguousallocationofelements,thestandardpro-videsslightlydifferentguaranteesfordifferentkindsofcontainers:[1]Guaranteesforvveeccttoorr(§16.
3)andddeeqquuee(§17.
2.
3):–Ifanexceptionisthrownbyappuusshh__bbaacckk()orappuusshh__ffrroonntt(),thatfunctionhasnoeffect.
–Unlessthrownbythecopyconstructorortheassignmentoperatoroftheelementtype,ifanexceptionisthrownbyaniinnsseerrtt(),thatfunctionhasnoeffect.
–Unlessthrownbythecopyconstructorortheassignmentoperatoroftheelementtype,noeerraassee()throwsanexception.
–Noppoopp__bbaacckk()orppoopp__ffrroonntt()throwsanexception.
[2]Guaranteesforlliisstt(§17.
2.
2):–Ifanexceptionisthrownbyappuusshh__bbaacckk()orappuusshh__ffrroonntt(),thatfunctionhasnoeffect.
–Ifanexceptionisthrownbyaniinnsseerrtt(),thatfunctionhasnoeffect.
–Noeerraassee(),ppoopp__bbaacckk(),ppoopp__ffrroonntt(),sspplliiccee(),orrreevveerrssee()throwsanexception.
–Unlessthrownbyapredicateoracomparisonfunction,thelliissttmemberfunctionsrreemmoovvee(),rreemmoovvee__iiff(),uunniiqquuee(),ssoorrtt(),andmmeerrggee()donotthrowexceptions.
[3]Guaranteesforassociativecontainers(§17.
4):–Ifanexceptionisthrownbyaniinnsseerrtt()whileinsertingasingleelement,thatfunctionhasnoeffect.
–Noeerraassee()throwsanexception.
Notethatwherethestrongguaranteeisprovidedforanoperationonacontainer,alliterators,pointerstoelements,andreferencestoelementsremainvalidifanexceptionisthrown.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
956Standard-LibraryExceptionSafetyAppendixETheserulescanbesummarizedinatable:Container-OperationGuaranteesvectordequelistmapcclleeaarr(())nothrownothrownothrownothrow(copy)(copy)eerraassee(())nothrownothrownothrownothrow(copy)(copy)11--eelleemmeennttiinnsseerrtt(())strongstrongstrongstrong(copy)(copy)NN--eelleemmeennttiinnsseerrtt(())strongstrongstrongbasic(copy)(copy)mmeerrggee(())——nothrow—(comparison)ppuusshh__bbaacckk(())strongstrongstrong—ppuusshh__ffrroonntt(())—strongstrong—ppoopp__bbaacckk(())nothrownothrownothrow—ppoopp__ffrroonntt(())—nothrownothrow—rreemmoovvee(())——nothrow—(comparison)rreemmoovvee__iiff(())——nothrow—(predicate)rreevveerrssee(())——nothrow—sspplliiccee(())——nothrow—sswwaapp(())nothrownothrownothrownothrow(copy-of-comparison)uunniiqquuee(())——nothrow—(comparison)Inthistable:basicmeansthattheoperationprovidesonlythebasicguarantee(§E.
2)strongmeansthattheoperationprovidesthestrongguarantee(§E.
2)nothrowmeansthattheoperationdoesnotthrowanexception(§E.
2)—meansthattheoperationisnotprovidedasamemberofthiscontainerWhereaguaranteerequiresthatsomeuser-suppliedoperationsnotthrowexceptions,thoseoperationsareindicatedinparenthesesundertheguarantee.
Theserequirementsarepreciselystatedinthetextprecedingthetable.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
4.
1InsertionandRemovalofElements957Thesswwaapp()functionsdifferfromtheotherfunctionsmentionedbynotbeingmembers.
Theguaranteeforcclleeaarr()isderivedfromthatofferedbyeerraassee()(§16.
3.
6).
Thistablelistsguaranteesofferedinadditiontothebasicguarantee.
Consequentlythistabledoesnotlistoper-ations,suchasrreevveerrssee()anduunniiqquuee()forvveeccttoorr,thatareprovidedonlyasalgorithmsforallsequenceswithoutadditionalguarantees.
The''almostcontainer''bbaassiicc__ssttrriinngg(§17.
5,§20.
3)offersthebasicguaranteeforallopera-tions(§E.
5.
1).
Thestandardalsoguaranteesthatbbaassiicc__ssttrriinngg'seerraassee()andsswwaapp()don'tthrow,andoffersthestrongguaranteeforbbaassiicc__ssttrriinngg'siinnsseerrtt()andppuusshh__bbaacckk().
Inadditiontoensuringthatacontainerisunchanged,anoperationprovidingthestrongguaranteealsoleavesalliterators,pointers,andreferencesvalid.
Forexample:vvooiidduuppddaattee(mmaapp&mm,mmaapp::iitteerraattoorrccuurrrreenntt){XXxx;ssttrriinnggss;wwhhiillee(cciinn>>ss>>xx)ttrryy{ccuurrrreenntt=mm.
iinnsseerrtt(ccuurrrreenntt,mmaakkee__ppaaiirr(ss,xx));}ccaattcchh(.
.
.
){//herecurrentstilldenotesthecurrentelement}}E.
4.
2GuaranteesandTradeoffsThepatchworkofadditionalguaranteesreflectsimplementationrealities.
Programmerspreferthestrongguaranteewithasfewconditionsaspossible,buttheyalsotendtoinsistthateachindividualstandard-libraryoperationbeoptimallyefficient.
Bothconcernsarereasonable,butformanyoperations,itisnotpossibletosatisfybothsimultaneously.
Togiveabetterideaofthetradeoffsinvolved,I'llexaminewaysofaddingofsingleandmultipleelementstolliisstts,vveeccttoorrs,andmmaapps.
Consideraddingasingleelementtoalliissttoravveeccttoorr.
Asever,ppuusshh__bbaacckk()providesthesimplestwayofdoingthat:vvooiiddff(lliisstt&llsstt,vveeccttoorr&vveecc,ccoonnssttXX&xx){ttrryy{llsstt.
ppuusshh__bbaacckk(xx);//addtolist}ccaattcchh(.
.
.
){//lstisunchangedrreettuurrnn;}TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
958Standard-LibraryExceptionSafetyAppendixEttrryy{vveecc.
ppuusshh__bbaacckk(xx);//addtovector}ccaattcchh(.
.
.
){//vecisunchangedrreettuurrnn;}//lstandveceachhaveanewelementwiththevaluex}Providingthestrongguaranteeinthesecasesissimpleandcheap.
Itisalsoveryusefulbecauseitprovidesacompletelyexception-safewayofaddingelements.
However,ppuusshh__bbaacckk()isn'tdefinedforassociativecontainers–ammaapphasnobbaacckk().
Afterall,thelastelementofanassociativecontainerisdefinedbytheorderrelationratherthanbyposition.
Theguaranteesforiinnsseerrtt()areabitmorecomplicated.
Thereasonisthatsometimesiinnsseerrtt()hastoplaceanelementin''themiddle''ofacontainer.
Thisisnoproblemforalinkeddatastructure,suchaslliissttormmaapp.
However,ifthereisfreereservedspaceinavveeccttoorr,theobviousimplementationofvveeccttoorr::iinnsseerrtt()copiestheelementsaftertheinsertionpointtomakeroom.
Thisisoptimallyefficient,butthereisnosimplewayofrestoringavveeccttoorrifXX'scopyassignmentorcopyconstructorthrowsanexception(see§E.
8[10-11]).
Conse-quently,vveeccttoorrprovidesaguaranteethatisconditionaluponelementcopyoperationsnotthrowingexceptions.
However,lliissttandmmaappdon'tneedsuchacondition;theycansimplylinkinnewelementsafterdoinganynecessarycopying.
Asanexample,assumethatXX'scopyassignmentandcopyconstructorthrowXX::ccaannnnoott__ccooppyyiftheycannotsuccessfullycreateacopy:vvooiiddff(lliisstt&llsstt,vveeccttoorr&vveecc,mmaapp&mm,ccoonnssttXX&xx,ccoonnssttssttrriinngg&ss){ttrryy{llsstt.
iinnsseerrtt(llsstt.
bbeeggiinn(),xx);//addtolist}ccaattcchh(.
.
.
){//lstisunchangedrreettuurrnn;}ttrryy{vveecc.
iinnsseerrtt(vveecc.
bbeeggiinn(),xx);//addtovector}ccaattcchh(XX::ccaannnnoott__ccooppyy){//oops:vecmayormaynothaveanewelementrreettuurrnn;}ccaattcchh(.
.
.
){//vecisunchangedrreettuurrnn;}TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
4.
2GuaranteesandTradeoffs959ttrryy{mm.
iinnsseerrtt(mmaakkee__ppaaiirr(ss,xx));//addtomap}ccaattcchh(.
.
.
){//misunchangedrreettuurrnn;}//lstandveceachhaveanewelementwiththevaluex//mhasanelementwiththevalue(s,x)}IfXX::ccaannnnoott__ccooppyyiscaught,anewelementmayormaynothavebeeninsertedintovveecc.
Ifanewelementwasinserted,itwillbeanobjectinavalidstate,butitisunspecifiedexactlywhatthevalueis.
ItispossiblethatafterXX::ccaannnnoott__ccooppyy,someelementwillhavebeen''mysteri-ously''duplicated(see§E.
8[11]).
Alternatively,iinnsseerrtt()maybeimplementedsothatitdeletessome''trailing''elementstobecertainthatnoinvalidelementsareleftinacontainer.
Unfortunately,providingthestrongguaranteeforvveeccttoorr'siinnsseerrtt()withoutthecaveataboutexceptionsthrownbycopyoperationsisnotfeasible.
Thecostofcompletelyprotectingagainstanexceptionwhilemovingelementsinavveeccttoorrwouldbesignificantcomparedtosim-plyprovidingthebasicguaranteeinthatcase.
Elementtypeswithcopyoperationsthatcanthrowexceptionsarenotuncommon.
Exam-plesfromthestandardlibraryitselfarevveeccttoorr,vveeccttoorr>,andmmaapp.
Thelliissttandvveeccttoorrcontainersprovidethesameguaranteesforiinnsseerrtt()ofsingleandmulti-pleelements.
Thereasonissimplythatforvveeccttoorrandlliisstt,thesameimplementationstrategiesapplytobothsingle-elementandmultiple-elementiinnsseerrtt().
However,mmaappprovidesthestrongguaranteeforsingle-elementiinnsseerrtt(),butonlythebasicguaranteeformultiple-elementiinnsseerrtt().
Asingle-elementiinnsseerrtt()formmaappthatprovidesthestrongguaranteeiseasilyimplemented.
However,theobviousstrategyforimplementingmultiple-elementiinnsseerrtt()forammaappistoinsertthenewelementsoneafteranother,anditisnoteasytoprovidethestrongguar-anteeforthat.
Theproblemwiththisisthatthereisnosimplewayofbackingoutofprevioussuccessfulinsertionsiftheinsertionofanelementfails.
Ifwewantaninsertionfunctionthatprovidesthestrongguaranteethateithereveryelementwassuccessfullyaddedortheoperationhadnoeffect,wecanbuilditbyconstructinganewcontainerandthensswwaapp():tteemmppllaatteevvooiiddssaaffee__iinnsseerrtt(CC&cc,ttyyppeennaammeeCC::ccoonnsstt__iitteerraattoorrii,IItteerrbbeeggiinn,IItteerreenndd){CCttmmpp(cc.
bbeeggiinn(),ii);//copyleadingelementstotemporaryccooppyy(bbeeggiinn,eenndd,iinnsseerrtteerr(ttmmpp,ttmmpp.
eenndd(copynewelementsccooppyy(ii,cc.
eenndd(),iinnsseerrtteerr(ttmmpp,ttmmpp.
eenndd(copytrailingelementssswwaapp(cc,ttmmpp);}Asever,thiscodemaymisbehaveiftheelementdestructorthrowsanexception.
However,ifanelementcopyoperationthrowsanexception,theargumentcontainerisunchanged.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
960Standard-LibraryExceptionSafetyAppendixEE.
4.
3SwapLikecopyconstructorsandassignments,sswwaapp()operationsareessentialtomanystandardalgorithmsandareoftensuppliedbyusers.
Forexample,ssoorrtt()andssttaabbllee__ssoorrtt()typicallyreorderelements,usingsswwaapp().
Thus,ifasswwaapp()functionthrowsanexceptionwhileexchangingvaluesfromacontainer,thecontainercouldbeleftwithunchangedelementsoraduplicateelementratherthanapairofswappedelements.
Considertheobviousdefinitionofthestandard-librarysswwaapp()function(§18.
6.
8):tteemmppllaatteevvooiiddsswwaapp(TT&aa,TT&bb){TTttmmpp=aa;aa=bb;bb=ttmmpp;}Clearly,sswwaapp()doesn'tthrowanexceptionunlesstheelementtype'scopyconstructororcopyassignmentdoes.
Withoneminorexceptionforassociativecontainers,standardcontainersswwaapp()functionsareguaranteednottothrowexceptions.
Basically,containersareswappedbyexchangingthedatastructuresthatactashandlesfortheelements(§13.
5,§17.
1.
3).
Sincetheelementsthem-selvesarenotmoved,elementconstructorsandassignmentsarenotinvoked,sotheydon'tgetanopportunitytothrowanexception.
Inaddition,thestandardguaranteesthatnostandard-librarysswwaapp()functioninvalidatesanyreferences,pointers,oriteratorsreferringtotheele-mentsofthecontainersbeingswapped.
Thisleavesonlyonepotentialsourceofexceptions:Thecomparisonobjectinanassociativecontaineriscopiedaspartofthehandle.
Theonlypos-sibleexceptionfromasswwaapp()ofstandardcontainersisthecopyconstructorandassignmentofthecontainer'scomparisonobject(§17.
1.
4.
1).
Fortunately,comparisonobjectsusuallyhavetrivialcopyoperationsthatdonothaveopportunitiestothrowexceptions.
Auser-suppliedsswwaapp()shouldbewrittentoprovidethesameguarantees.
Thisisrela-tivelysimpletodoaslongasonerememberstoswaptypesrepresentedashandlesbyswappingtheirhandles,ratherthanslowlyandelaboratelycopyingtheinformationreferredtobythehan-dles(§13.
5,§16.
3.
9,§17.
1.
3).
E.
4.
4InitializationandIteratorsAllocationofmemoryforelementsandtheinitializationofsuchmemoryarefundamentalpartsofeverycontainerimplementation(§E.
3).
Consequently,thestandardalgorithmsforconstruct-ingobjectsinuninitializedmemory–uunniinniittiiaalliizzeedd__ffiillll(),uunniinniittiiaalliizzeedd__ffiillll__nn(),anduunniinniittiiaalliizzeedd__ccooppyy()(§19.
4.
4)–areguaranteedtoleavenoconstructedobjectsbehindiftheythrowanexception.
Theyprovidethestrongguarantee(§E.
2).
Thissometimesinvolvesdestroyingelements,sotherequirementthatdestructorsnotthrowexceptionsisessentialtothesealgorithms;see§E.
8[14].
Inaddition,theiteratorssuppliedasargumentstothesealgo-rithmsarerequiredtobewellbehaved.
Thatis,theymustbevaliditerators,refertovalidsequences,anditeratoroperations(suchas++and!
=and*)onavaliditeratorarenotallowedtothrowexceptions.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
4.
4InitializationandIterators961Iteratorsareexamplesofobjectsthatarecopiedfreelybystandardalgorithmsandopera-tionsonstandardcontainers.
Thus,copyconstructorsandcopyassignmentsofiteratorsshouldnotthrowexceptions.
Inparticular,thestandardguaranteesthatnocopyconstructororassign-mentoperatorofaniteratorreturnedfromastandardcontainerthrowsanexception.
Forexam-ple,aniteratorreturnedbyvveeccttoorr::bbeeggiinn()canbecopiedwithoutfearofexceptions.
Notethat++and--onaniteratorcanthrowexceptions.
Forexample,aniissttrreeaammbbuuff__iitteerraattoorr(§19.
2.
6)couldreasonablythrowanexceptiontoindicateaninputerror,andarange-checkediteratorcouldthrowanexceptiontoindicateanattempttomoveoutsideitsvalidrange(§19.
3).
However,theycannotthrowexceptionswhenmovinganiteratorfromoneelementofasequencetoanother,withoutviolatingthedefinitionof++and--onaniterator.
Thus,uunniinniittiiaalliizzeedd__ffiillll(),uunniinniittiiaalliizzeedd__ffiillll__nn(),anduunniinniittiiaalliizzeedd__ccooppyy()assumethat++and--ontheiriteratorargumentswillnotthrow;iftheydothrow,eitherthose''iterators''weren'titeratorsaccordingtothestandard,orthe''sequence''specifiedbythemwasn'tasequence.
Again,thestandardcontainersdonotprotecttheuserfromtheuser'sownundefinedbehavior(§E.
2).
E.
4.
5ReferencestoElementsWhenareference,apointer,oraniteratortoanelementofacontainerishandedtosomecode,thatcodecancorruptthecontainerbycorruptingtheelement.
Forexample:vvooiiddff(ccoonnssttXX&xx){lliissttllsstt;llsstt.
ppuusshh__bbaacckk(xx);lliisstt::iitteerraattoorrii=llsstt.
bbeeggiinn();*ii=xx;//copyxintolist//.
.
.
}Ifxxiscorrupted,lliisstt'sdestructormaynotbeabletoproperlydestroyllsstt.
Forexample:ssttrruuccttXX{iinntt*pp;XX(){pp=nneewwiinntt;}XX(){ddeelleetteepp;}//.
.
.
};vvooiiddmmaalliicciioouuss(){XXxx;xx.
pp=rreeiinntteerrpprreett__ccaasstt(77);//corruptxff(xx);//timebomb}Whentheexecutionreachestheendonff(),thelliissttdestructoriscalled,andthatwillinturninvokeXX'sdestructorforthecorruptedvalue.
Theeffectofexecutingddeelleetteeppwhenppisn't00anddoesn'tpointtoanXXisundefinedandcouldbeanimmediatecrash.
Alternatively,itTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
962Standard-LibraryExceptionSafetyAppendixEmightleavethefreestorecorruptedinawaythatcausesdifficult-to-trackproblemsmuchlateroninanapparentlyunrelatedpartofaprogram.
Thispossibilityofcorruptionshouldnotstoppeoplefrommanipulatingcontainerelementsthroughreferencesanditerators;itisoftenthesimplestandmostefficientwayofdoingthings.
However,itiswisetotakeextracarewithsuchreferencesintocontainers.
Whentheintegrityofacontaineriscrucial,itmightbeworthwhiletooffersaferalternativestolessexperiencedusers.
Forexample,wemightprovideanoperationthatchecksthevalidityofanewelementbeforecopyingitintoanimportantcontainer.
Naturally,suchcheckingcanonlybedonewithknowledgeoftheapplicationtypes.
Ingeneral,ifanelementofacontaineriscorrupted,subsequentoperationsonthecontainercanfailinnastyways.
Thisisnotparticulartocontainers.
Anyobjectleftinabadstatecancausesubsequentfailure.
E.
4.
6PredicatesManystandardalgorithmsandmanyoperationsonstandardcontainersrelyonpredicatesthatcanbesuppliedbyusers.
Inparticular,allassociativecontainersdependonpredicatesforbothlookupandinsertion.
Apredicateusedbyastandardcontaineroperationmaythrowanexception.
Inthatcase,everystandard-libraryoperationprovidesthebasicguarantee,andsomeoperations,suchasiinnsseerrtt()ofasingleelement,providethestrongguarantee(§E.
4.
1).
Ifapredicatethrowsanexceptionfromanoperationonacontainer,theresultingsetofelementsinthecontainermaynotbeexactlywhattheuserwanted,butitwillbeasetofvalidelements.
Forexample,if==throwsanexceptionwheninvokedfromlliisstt::uunniiqquuee()(§17.
2.
2.
3),theusercannotassumethatnoduplicatesareinthelist.
Alltheusercansafelyassumeisthateveryelementonthelistisvalid(see§E.
5.
3).
Fortunately,predicatesrarelydoanythingthatmightthrowanexception.
However,user-defined::iitteerraattoorrsandbbaassiicc__ssttrriinngg::ccoonnsstt__iitteerraattoorrs.
Consequently,astringimplementationoffersthebasicguarantee(§E.
2),andtheguaranteesforeerraassee(),iinnsseerrtt(),ppuusshh__bbaacckk()andsswwaapp()(§E.
4.
1)applytobbaassiicc__ssttrriinnggs.
Forexample,bbaassiicc__ssttrriinngg::ppuusshh__bbaacckk()offersthestrongguarantee.
E.
5.
2StreamsIfrequiredtodoso,iostreamfunctionsthrowexceptionstosignalstatechanges(§21.
3.
6).
Thesemanticsofthisarewelldefinedandposenoexception-safetyproblems.
Ifauser-definedooppeerraattoorr>()throwsanexception,itmayappeartotheuserasiftheios-treamlibrarythrewanexception.
However,suchanexceptionwillnotaffectthestreamstate(§21.
3.
3).
Furtheroperationsonthestreammaynotfindtheexpecteddata–becausetheprevi-ousoperationthrewanexceptioninsteadofcompletingnormally–butthestreamitselfisuncorrupted.
AseverafteranI/Oproblem,acclleeaarr()maybeneededbeforedoingfurtherreads/writes(§21.
3.
3,§21.
3.
5).
Likebbaassiicc__ssttrriinngg,theiostreamsrelyoncchhaarr__ttrraaiittsstomanipulatecharacters(§20.
2.
1,§E.
5.
1).
Thus,animplementationcanassumethatoperationsoncharactersdonotthrowexcep-tions,andnoguaranteesaremadeiftheuserviolatesthatassumption.
Toallowforcrucialoptimizations,llooccaallees(§D.
2)andffaacceetts(§D.
3)areassumednottothrowexceptions.
Iftheydo,astreamusingthemcouldbecorrupted.
However,themostlikelyexception,assttdd::bbaadd__ccaassttfromauussee__ffaacceett(§D.
3.
1),canoccuronlyinuser-suppliedcodeoutsidethestandardstreamimplementation.
Atworst,thiswillproduceincompleteoutputorcauseareadtofailratherthancorrupttheoossttrreeaamm(oriissttrreeaamm)itself.
E.
5.
3AlgorithmsAsidefromuunniinniittiiaalliizzeedd__ccooppyy(),uunniinniittiiaalliizzeedd__ffiillll(),anduunniinniittiiaalliizzeedd__ffiillll__nn()(§E.
4.
4),thestandardoffersonlythebasicguarantee(§E.
2)foralgorithms.
Thatis,providedthatuser-suppliedobjectsarewellbehaved,thealgorithmswillmaintainallstandard-libraryinvariantsandleaknoresources.
Toavoidundefinedbehavior,user-suppliedoperationsshouldalwaysleavetheiroperandsinvalidstates,anddestructorsshouldnotthrowexceptions.
Thealgorithmsthemselvesdonotthrowexceptions.
Instead,theyreporterrorsandfailuresthroughtheirreturnvalues.
Forexample,searchalgorithmsgenerallyreturntheendofasequencetoindicate''notfound''(§18.
2).
Thus,exceptionsthrownfromastandardalgorithmTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
964Standard-LibraryExceptionSafetyAppendixEmustoriginatefromauser-suppliedoperation.
Thatis,theexceptionmustcomefromanopera-tiononanelement–suchasapredicate(§18.
4),anassignment,orasswwaapp()–orfromanallo-cator(§19.
4).
Ifsuchanoperationthrowsanexception,thealgorithmterminatesimmediately,anditisuptothefunctionsthatinvokedthealgorithmtohandletheexception.
Forsomealgorithms,itispossibleforanexceptiontooccuratapointwherethecontainerisnotinastatethattheuserwouldconsidergood.
Forexample,somesortingalgorithmstemporarilycopyelementsintoabufferandlaterputthembackintothecontainer.
Suchassoorrtt()mightcopyelementsoutofthecontainer(planningtowritethembackinproperorderlater),overwritethem,andthenthrowanexception.
Fromauser'spointofview,thecontainerwascorrupted.
However,allelementsareinavalidstate,sorecoveryshouldbereasonablystraightforward.
Notethatthestandardalgorithmsaccesssequencesthroughiterators.
Thatis,thestandardalgorithmsneveroperateoncontainersdirectly,onlyonelementsinacontainer.
Thefactthatastandardalgorithmneverdirectlyaddsorremoveselementsfromacontainersimplifiestheanalysisoftheimpactofexceptions.
Similarly,ifadatastructureisaccessedonlythroughiter-ators,pointers,andreferencestoccoonnsstt(forexample,throughaccoonnssttRReecc*),itisusuallytrivialtoverifythatanexceptionhasnoundesiredeffects.
E.
5.
4ValarrayandComplexThenumericfunctionsdonotexplicitlythrowexceptions(Chapter22).
However,vvaallaarrrraayyneedstoallocatememoryandthusmightthrowssttdd::bbaadd__aalllloocc.
Furthermore,vvaallaarrrraayyorccoommpplleexxmaybegivenanelementtype(scalartype)thatthrowsexceptions.
Asever,thestan-dardlibraryprovidesthebasicguarantee(§E.
2),butnospecificguaranteesaremadeabouttheeffectsofacomputationterminatedbyanexception.
Likebbaassiicc__ssttrriinngg(§E.
5.
1),vvaallaarrrraayyandccoommpplleexxareallowedtoassumethattheirtemplateargumenttypedoesnothaveuser-definedcopyoperationssothattheycanbebitwisecopied.
Typically,thesestandard-librarynumerictypesareoptimizedforspeed,assumingthattheirele-menttype(scalartype)doesnotthrowexceptions.
E.
5.
5TheCStandardLibraryAstandard-libraryoperationwithoutanexceptionspecificationmaythrowexceptionsinanimplementation-definedmanner.
However,functionsfromthestandardClibrarydonotthrowexceptionsunlesstheytakeafunctionargumentthatdoes.
Afterall,thesefunctionsaresharedwithC,andCdoesn'thaveexceptions.
AnimplementationmaydeclareastandardCfunctionwithanemptyexception-specification,tthhrrooww(),tohelpthecompilergeneratebettercode.
Functionssuchasqqssoorrtt()andbbsseeaarrcchh()(§18.
11)takeapointertofunctionasargument.
Theycanthereforethrowanexceptioniftheirargumentscan.
Thebasicguarantee(§E.
2)cov-ersthesefunctions.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
6ImplicationsforLibraryUsers965E.
6ImplicationsforLibraryUsersOnewaytolookatexceptionsafetyinthecontextofthestandardlibraryisthatwehavenoproblemsunlesswecreatethemforourselves:Thelibrarywillfunctioncorrectlyaslongasuser-suppliedoperationsmeetthestandardlibrary'sbasicrequirements(§E.
2).
Inparticular,noexceptionthrownbyastandardcontaineroperationwillcausememoryleaksfromcontainersorleaveacontainerinaninvalidstate.
Thus,theproblemforthelibraryuserbecomes:HowcanIdefinemytypessothattheydon'tcauseundefinedbehaviororleakresourcesThebasicrulesare:[1]Whenupdatinganobject,don'tdestroyitsoldrepresentationbeforeanewrepresenta-tioniscompletelyconstructedandcanreplacetheoldonewithoutriskofexceptions.
Forexample,seetheimplementationsofvveeccttoorr::ooppeerraattoorr=(),ssaaffee__aassssiiggnn(),andvveeccttoorr::ppuusshh__bbaacckk()in§E.
3.
[2]Beforethrowinganexception,releaseeveryresourceacquiredthatisnotownedbysome(other)object.
[2a]The''resourceacquisitionisinitialization''technique(§14.
4)andthelanguagerulethatpartiallyconstructedobjectsaredestroyedtotheextentthattheywerecon-structed(§14.
4.
1)canbemosthelpfulhere.
Forexample,seelleeaakk()in§E.
2.
[2b]Theuunniinniittiiaalliizzeedd__ccooppyy()algorithmanditscousinsprovideautomaticreleaseofresourcesincaseoffailuretocompleteconstructionofasetofobjects(§E.
4.
4).
[3]Beforethrowinganexception,makesurethateveryoperandisinavalidstate.
Thatis,leaveeachobjectinastatethatallowsittobeaccessedanddestroyedwithoutcausingundefinedbehaviororanexceptiontobethrownfromadestructor.
Forexample,seevveeccttoorr'sassignmentin§E.
3.
2.
[3a]Notethatconstructorsarespecialinthatwhenanexceptionisthrownfromacon-structor,noobjectisleftbehindtobedestroyedlater.
Thisimpliesthatwedon'thavetoestablishaninvariantandthatwemustbesuretoreleaseallresourcesacquiredduringafailedconstructionbeforethrowinganexception.
[3b]Notethatdestructorsarespecialinthatanexceptionthrownfromadestructoralmostcertainlyleadstoviolationofinvariantsand/orcallstotteerrmmiinnaattee().
Inpractice,itcanbesurprisinglydifficulttofollowtheserules.
Theprimaryreasonisthatexceptionscanbethrownfromplaceswherepeopledon'texpectthem.
Agoodexampleisssttdd::bbaadd__aalllloocc.
Everyfunctionthatdirectlyorindirectlyusesnneewworanaallllooccaattoorrtoacquirememorycanthrowbbaadd__aalllloocc.
Insomeprograms,wecansolvethisparticularproblembynotrunningoutofmemory.
However,forprogramsthataremeanttorunforalongtimeortoacceptarbitraryamountsofinput,wemustexpecttohandlevariousfailurestoacquireresources.
Thus,wemustassumeeveryfunctioncapableofthrowinganexceptionuntilwehaveprovedotherwise.
Onesimplewaytotrytoavoidsurprisesistousecontainersofelementsthatdonotthrowexceptions(suchascontainersofpointersandcontainersofsimpleconcretetypes)orlinkedcontainers(suchaslliisstt)thatprovidethestrongguarantee(§E.
4).
Another,complementary,approachistorelyprimarilyonoperations,suchasppuusshh__bbaacckk(),thatofferthestrongguaran-teethatanoperationeithersucceedsorhasnoeffect(§E.
2).
However,theseapproachesarebythemselvesinsufficienttoavoidresourceleaksandcanleadtoanadhoc,overlyrestrictive,andTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
966Standard-LibraryExceptionSafetyAppendixEpessimisticapproachtoerrorhandlingandrecovery.
Forexample,avveeccttoorristriviallyexceptionsafeifoperationsonTTdon'tthrowexceptions.
However,unlesstheobjectspointedtoaredeletedsomewhere,anexceptionfromthevveeccttoorrwillleadtoaresourceleak.
Thus,introducingaHHaannddlleeclasstodealwithdeallocation(§25.
7)andusingvveeccttoorr>ratherthantheplainvveeccttoorrwillprobablyimprovetheresilienceofthecode.
Whenwritingnewcode,itispossibletotakeamoresystematicapproachandmakesurethateveryresourceisrepresentedbyaclasswithaninvariantthatprovidesthebasicguarantee(§E.
2).
Giventhat,itbecomesfeasibletoidentifythecriticalobjectsinanapplicationandpro-videroll-backsemantics(thatis,thestrongguarantee–possiblyundersomespecificcondi-tions)foroperationsonsuchobjects.
Mostapplicationscontaindatastructuresandcodethatarenotwrittenwithexceptionsafetyinmind.
Wherenecessary,suchcodecanbefittedintoanexception-safeframeworkbyeitherverifyingthatitdoesn'tthrowexceptions(aswasthecasefortheCstandardlibrary;§E.
5.
5)orthroughtheuseofinterfaceclassesforwhichtheexceptionbehaviorandresourcemanagementcanbepreciselyspecified.
Whendesigningtypesintendedforuseinanexception-safeenvironment,wemustpayspe-cialattentiontotheoperationsusedbythestandardlibrary:constructors,destructors,assign-ments,comparisons,swapfunctions,functionsusedaspredicates,andoperationsoniterators.
Thisisbestdonebydefiningaclassinvariantthatcanbesimplyestablishedbyallconstructors.
Sometimes,wemustdesignourclassinvariantssothatwecanputanobjectintoastatewhereitcanbedestroyedevenwhenanoperationsuffersafailureatan''inconvenient''point.
Ide-ally,thatstateisn'tanartifactdefinedsimplytoaidexceptionhandling,butastatethatfollowsnaturallyfromthesemanticsofthetype(§E.
3.
5).
Whenconsideringexceptionsafety,theemphasisshouldbeondefiningvalidstatesforobjects(invariants)andonproperreleaseofresources.
Itisthereforeimportanttorepresentresourcesdirectlyasclasses.
Thevveeccttoorr__bbaassee(§E.
3.
2)isasimpleexampleofthis.
Thecon-structorsforsuchresourceclassesacquirelower-levelresources(suchastherawmemoryforvveeccttoorr__bbaassee)andestablishinvariants(suchastheproperinitializationofthepointersofavveeccttoorr__bbaassee).
Thedestructorsofsuchclassesimplicitlyfreelower-levelresources.
Therulesforpartialconstruction(§14.
4.
1)andthe''resourceacquisitionisinitialization''technique(§14.
4)supportthiswayofhandlingresources.
Awell-writtenconstructorestablishestheclassinvariantforanobject(§24.
3.
7.
1).
Thatis,theconstructorgivestheobjectavaluethatallowssubsequentoperationstobewrittensimplyandtocompletesuccessfully.
Thisimpliesthataconstructoroftenneedstoacquireresources.
Ifthatcannotbedone,theconstructorcanthrowanexceptionsothatwecandealwiththatproblembeforeanobjectiscreated.
Thisapproachisdirectlysupportedbythelanguageandthestandardlibrary(§E.
3.
5).
Therequirementtoreleaseresourcesandtoplaceoperandsinvalidstatesbeforethrowinganexceptionmeansthattheburdenofexceptionhandlingissharedamongthefunctionthrow-ing,thefunctionsonthecallchaintothehandler,andthehandler.
Throwinganexceptiondoesnotmakehandlinganerror''somebodyelse'sproblem.
''Itistheobligationoffunctionsthrowingorpassingalonganexceptiontoreleaseresourcesthattheyownandtoputoperandsinconsistentstates.
Unlesstheydothat,anexceptionhandlercandolittlemorethantrytoter-minategracefully.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
SectionE.
7Advice967E.
7Advice[1]Beclearaboutwhatdegreeofexceptionsafetyyouwant;§E.
2.
[2]Exceptionsafetyshouldbepartofanoverallstrategyforfaulttolerance;§E.
2.
[3]Providethebasicguaranteeforallclasses.
Thatis,maintainaninvariant,anddon'tleakresources;§E.
2,§E.
3.
2,§E.
4.
[4]Wherepossibleandaffordable,providethestrongguaranteethatanoperationeithersuc-ceedsorleavesalloperandsunchanged;§E.
2,§E.
3.
[5]Don'tthrowanexceptionfromadestructor;§E.
2,§E.
3.
2,§E.
4.
[6]Don'tthrowanexceptionfromaniteratornavigatingavalidsequence;§E.
4.
1,§E.
4.
4.
[7]Exceptionsafetyinvolvescarefulexaminationofindividualoperations;§E.
3.
[8]Designtemplatestobetransparenttoexceptions;§E.
3.
1.
[9]Prefertheconstructorapproachtoresourcerequisitiontousingiinniitt()functions;§E.
3.
5.
[10]Defineaninvariantforaclasstomakeitclearwhatisavalidstate;§E.
2,§E.
6.
[11]Makesurethatanobjectcanalwaysbeputintoavalidstatewithoutfearofanexceptionbeingthrown;§E.
3.
2,§E.
6.
[12]Keepinvariantssimple;§E.
3.
5.
[13]Leavealloperandsinvalidstatesbeforethrowinganexception;§E.
2,§E.
6.
[14]Avoidresourceleaks;§E.
2,§E.
3.
1,§E.
6.
[15]Representresourcesdirectly;§E.
3.
2,§E.
6.
[16]Rememberthatsswwaapp()cansometimesbeanalternativetocopyingelements;§E.
3.
3.
[17]Wherepossible,relyonorderingofoperationsratherthanonexplicituseoftry-blocks;§E.
3.
4.
[18]Don'tdestroy''old''informationuntilitsreplacementhasbeensafelyproduced;§E.
3.
3,§E.
6.
[19]Relyonthe''resourceacquisitionisinitialization''technique;§E.
3,§E.
3.
2,§E.
6.
[20]Makesurethatcomparisonoperationsforassociativecontainerscanbecopied;§E.
3.
3.
[21]Identifycriticaldatastructuresandprovidethemwithoperationsthatprovidethestrongguarantee;§E.
6E.
8Exercises1.
(1)Listallexceptionsthatcouldpossiblybethrownfromff()in§E.
1.
2.
(1)Answerthequestionsaftertheexamplein§E.
1.
3.
(1)DefineaclassTTeesstteerrthatoccasionallythrowsexceptionsfrombasicoperations,suchascopyconstructors.
UseTTeesstteerrtotestyourstandard-librarycontainers.
4.
(1)Findtheerrorinthe''messy''versionofvveeccttoorr'sconstructor(§E.
3.
1),andwriteaprogramtogetittocrash.
Hint:Firstimplementvveeccttoorr'sdestructor.
5.
(2)Implementasimplelistprovidingthebasicguarantee.
Beveryspecificaboutwhatthelistrequiresofitsuserstoprovidetheguarantee.
6.
(3)Implementasimplelistprovidingthestrongguarantee.
Carefullytestthislist.
Giveanargumentwhypeopleshouldbelieveittobesafe.
7.
(2.
5)ReimplementSSttrriinnggfrom§11.
12tobeassafeasastandardcontainer.
8.
(2)Comparetheruntimeofthevariousversionsofvveeccttoorr'sassignmentandTheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.
968Standard-LibraryExceptionSafetyAppendixEssaaffee__aassssiiggnn()(§E.
3.
3).
9.
(1.
5)Copyanallocatorwithoutusinganassignmentoperator(asneededtoimproveooppeerraattoorr=()in§E.
3.
3).
10.
(2)Addsingle-elementandmultiple-elementeerraassee()andiinnsseerrtt()thatprovidethebasicguaranteetovveeccttoorr(§E.
3.
2).
11.
(2)Addsingle-elementandmultiple-elementeerraassee()andiinnsseerrtt()thatprovidethestrongguaranteetovveeccttoorr(§E.
3.
2).
Comparethecostandcomplexityofthesesolutionstothesolutionstoexercise10.
12.
(2)Writeassaaffee__iinnsseerrtt()(§E.
4.
2)thatinsertselementsintotheexistingvveeccttoorr(ratherthancopyingtoatemporary).
Whatconstraintsdoyouhavetoimposeonoperations13.
(2)Writeassaaffee__iinnsseerrtt()(§E.
4.
2)thatinsertselementsintotheexistingmmaapp(ratherthancopyingtoatemporary).
Whatconstraintsdoyouhavetoimposeonoperations14.
(2.
5)Comparethesize,complexity,andperformanceofthessaaffee__iinnsseerrtt()functionsfromexercises12and13tothessaaffee__iinnsseerrtt()from§E.
4.
2.
15.
(2.
5)Writeabetter(simplerandfaster)ssaaffee__iinnsseerrtt()forassociativecontainersonly.
Usetraitstowriteassaaffee__iinnsseerrtt()thatautomaticallyselectstheoptimalssaaffee__iinnsseerrtt()foracontainer.
Hint:§19.
2.
3.
16.
(2.
5)Trytorewriteuunniinniittiiaalliizzeedd__ffiillll()(§19.
4.
4,§E.
3.
1)tohandledestructorsthatthrowexceptions.
IsthatpossibleIfso,atwhatcostIfnot,whynot17.
(2.
5)Trytorewriteuunniinniittiiaalliizzeedd__ffiillll()(§19.
4.
4,§E.
3.
1)tohandleiteratorsthatthrowexceptionsfor++and--.
IsthatpossibleIfso,atwhatcostIfnot,whynot18.
(3)Takeacontainerfromalibrarydifferentfromthestandardlibrary.
Examineitsdocu-mentationtoseewhatexception-safetyguaranteesitprovides.
Dosometeststoseehowresilientitisagainstexceptionsthrownbymemoryallocationanduser-suppliedcode.
Compareittoacorrespondingstandard-librarycontainer.
19.
(3)Trytooptimizethevveeccttoorrfrom§E.
3bydisregardingthepossibilityofexceptions.
Forexample,removealltry-blocks.
Comparetheperformanceagainsttheversionfrom§E.
3andagainstastandard-libraryvveeccttoorrimplementation.
Also,comparethesizeandthecomplexityofthesourcecodeofthesedifferentvveeccttoorrs.
20.
(1)Defineinvariantsforvveeccttoorr(§E.
3)withandwithoutthepossibilityofvv==00(§E.
3.
5).
21.
(2.
5)Readthesourceofanimplementationofvveeccttoorr.
Whatguaranteesareimplementedforassignment,multi-elementiinnsseerrtt(),andrreessiizzee()22.
(3)Writeaversionofhhaasshh__mmaapp(§17.
6)thatisassafeasastandardcontainer.
TheC++ProgrammingLanguage,SpecialEditionbyBjarneStroustrup.
Copyright2000byAT&T.
PublishedbyAddisonWesleyInc.
ISBN0-201-70073-5.
Allrightsreserved.

paypal$10的代金券,选购美国VPS

paypal贝宝可撸$10的代金券!这两天paypal出了活动,本次并没有其他的限制,只要注册国区的paypal,使用国内的手机号和62开头的银联卡,就可以获得10美元的代金券,这个代金券购买产品需要大于10.1美元,站长给大家推荐几个方式,可以白嫖一年的VPS,有需要的朋友可以看看比较简单。PayPal送10美元活动:点击直达活动sfz与绑定卡的号码可以重复用 注册的邮箱,手机号与绑的银联卡必须...

PQ.hosting:香港HE/乌克兰/俄罗斯/荷兰/摩尔多瓦/德国/斯洛伐克/捷克vps,2核/2GB内存/30GB NVMe空间,€3/月

PQ.hosting怎么样?PQ.hosting是一家俄罗斯商家,正规公司,主要提供KVM VPS和独立服务器,VPS数据中心有香港HE、俄罗斯莫斯科DataPro、乌克兰VOLIA、拉脱维亚、荷兰Serverius、摩尔多瓦Alexhost、德国等。部分配置有变化,同时开通Paypal付款。香港、乌克兰、德国、斯洛伐克、捷克等为NVMe硬盘。香港为HE线路,三网绕美(不太建议香港)。免费支持wi...

imidc:$88/月,e3-1230/16G内存/512gSSD/30M直连带宽/13个IPv4日本多IP

imidc对日本独立服务器在搞特别促销,原价159美元的机器现在只需要88美元,而且给13个独立IPv4,30Mbps直连带宽,不限制流量。注意,本次促销只有一个链接,有2个不同的优惠码,你用不同的优惠码就对应着不同的配置,价格也不一样。88美元的机器,下单后默认不管就给512G SSD,要指定用HDD那就发工单,如果需要多加一个/28(13个)IPv4,每个月32美元...官方网站:https:...

neverletgo为你推荐
域名服务域名服务器是什么?有什么作用免费vps服务器有没有便宜的vps,最好是免费的asp网站空间什么是ASP空间?手机网站空间手机网页空间需要多大?手机网站空间QQ空间技巧的手机网站啊?大连虚拟主机大连建网站哪里好?最好的虚拟主机哪家的虚拟主机比较好?jsp虚拟主机jsp中文网的虚拟主机有人用过没?觉得怎么样?河南虚拟主机谁那有好的虚拟主机?广西虚拟主机网站icp备案流程
已经备案域名 ftp空间 美国主机评测 fastdomain bandwagonhost iisphpmysql seovip 新站长网 gg广告 工作站服务器 北京双线 域名和空间 免费申请网站 国外免费asp空间 hdd 爱奇艺会员免费试用 常州联通宽带 如何建立邮箱 国外视频网站有哪些 下载速度测试 更多