thinking in c++ 2nd ed volume 2
DESCRIPTION
Thinking in C++, Bruce EckelTRANSCRIPT
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 1/458
ThinkingInC++Volume2:PracticalProgramming
BruceEckel,President,MindView,Inc.ChuckAllison,UtahValleyStateCollege
BookHomePageAnnotatedSolutionGuide
ReportErrorsHere
CoverIntroduction
Part1:BuildingStableSystems1:Exceptionhandling2:Defensiveprogramming
Part2:TheStandardC++Library3:Stringsindepth4:Iostreams5:Templatesindepth6:Genericalgorithms7:Genericcontainers
Part3:SpecialTopics8:Runtimetypeidentification9:Multipleinheritance10:Designpatterns11:Concurrency
AppendixA:RecommendedreadingB:EtcIndex
Idliketocongratulatethebothofyouforaveryimpressivework!NotonlydidIfindyourbooktobeanenjoyableandrewardingreadIwasastoundedbytheaccuracybothintermsoftechnicalcorrectnessanduseofthelanguageIbelievethatyouhaveattainedalevelofcraftsmanshipthatissimplyoutstanding.
BjornKarlssonEditorialBoard,C/C++UsersJournal
Thisbookisatremendousachievement.Youoweittoyourselftohaveacopyonyourshelf.
AlStevensContributingEditor,DoctorDobbsJournal
Eckelsbookistheonlyonetosoclearlyexplainhowtorethinkprogramconstructionforobjectorientation.ThatthebookisalsoanexcellenttutorialontheinsandoutsofC++isanaddedbonus.
AndrewBinstockEditor,UnixReview
BrucecontinuestoamazemewithhisinsightintoC++,andThinkinginC++ishisbestcollectionofideasyet.IfyouwantclearanswerstodifficultquestionsaboutC++,buythisoutstandingbook.
GaryEntsminger
http://mindview.net:8080/TICPPV2/http://mindview.net/Books/TICPP/ThinkingInCPP2e.htmlhttp://mindview.net/Books/TICPPV2/Solutions
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 2/458
Author,TheTaoofObjects
ThinkinginC++patientlyandmethodicallyexplorestheissuesofwhenandhowtouseinlines,references,operatoroverloading,inheritanceanddynamicobjects,aswellasadvancedtopicssuchastheproperuseoftemplates,exceptionsandmultipleinheritance.TheentireeffortiswoveninafabricthatincludesEckelsownphilosophyofobjectandprogramdesign.AmustforeveryC++developersbookshelf,ThinkinginC++istheoneC++bookyoumusthaveifyouredoingseriousdevelopmentwithC++.
RichardHaleShawContributingEditor,PCMagazine
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 3/458
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 4/458
CIPDATAAVAILABLEVicePresidentandEditorialDirector,ECS:MarciaJ.HortonPublisher:AlanR.AptAssociateEditor:ToniDianneHolmEditorialAssistant:PatrickLindnerVicePresidentandDirectorofProductionandManufacturing,ESM:DavidW.RiccardiExecutiveManagingEditor:VinceOBrienManagingEditor:CamilleTrentacosteProductionEditor:IrwinZuckerDirectorofCreativeServices:PaulBelfantiCreativeDirector:CaroleAnsonCoverandInteriorDesigner:DanielWillHarrisCoverIllustrations:TinaJensenManufacturingManager:TrudyPisciottiManufacturingBuyer:LisaMcDowellMarketingManager:PamelaShaffer
2004MindView,Inc.PublishedbyPearsonPrenticeHallPearsonEducation,Inc.UpperSaddleRiver,NJ07458
Allrightsreserved.Nopartofthisbookmaybereproducedinanyformorbyanymeans,withoutpermissioninwritingfromthepublisher.PearsonPrenticeHallisatrademarkofPearsonEducation,Inc.
Theauthorsandpublisherofthisbookhaveusedtheirbesteffortsinpreparingthisbook.Theseeffortsincludethedevelopment,research,andtestingofthetheoriesandprogramstodeterminetheireffectiveness.Theauthorsand
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 5/458
publishermakenowarrantyofanykind,expressedorimplied,withregardtotheseprogramsorthedocumentationcontainedinthisbook.Theauthorsandpublishershallnotbeliableinanyeventforincidentalorconsequentialdamagesinconnectionwith,orarisingoutof,thefurnishing,performance,oruseoftheseprograms.PrintedintheUnitedStatesofAmerica
10987654321
ISBN0130353132
PearsonEducationLtd.,LondonPearsonEducationAustraliaPty.Ltd.,SydneyPearsonEducationSingapore,Pte.Ltd.PearsonEducationNorthAsiaLtd.,HongKongPearsonEducationCanada,Inc.,TorontoPearsonEducacindeMexico,S.A.deC.V.PearsonEducationJapan,TokyoPearsonEducationMalaysia,Pte.Ltd.PearsonEducation,Inc.,UpperSaddleRiver,NewJersey
DedicationToallthosewhohaveworkedtirelessly
todeveloptheC++language
WhatsinsideIntroduction1
Goals..........................................1Chapters.....................................2Exercises.....................................5
Exercisesolutions...............5Sourcecode.................................5Compilers....................................7Languagestandards.....................9Seminars,CDROMs&consulting.................................9Errors.......................................10Aboutthecover.........................10Acknowledgements.....................10
I:BuildingStableSystems13
1:ExceptionHandling15Traditionalerrorhandling.............16Throwinganexception................18Catchinganexception.................20
Thetryblock....................20Exceptionhandlers...........20Terminationandresumption................22
Exceptionmatching.....................23Catchinganyexception.....25Rethrowinganexception...26Uncaughtexceptions.........26
Cleaningup................................28Resourcemanagement.....30Makingeverythinganobject.........................32auto_ptr..........................35Functionleveltryblocks...36
Standardexceptions...................38Exceptionspecifications...............40
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 6/458
Betterexceptionspecifications?..................45Exceptionspecificationsandinheritance................46Whennottouseexceptionspecifications.....47
Exceptionsafety.........................48Programmingwithexceptions.......52
Whentoavoidexceptions..52Typicalusesofexceptions.54
Overhead...................................58Summary...................................60Exercises...................................61
2:DefensiveProgramming63Assertions.................................66Asimpleunittestframework........70
Automatedtesting............71TheTestSuiteFramework..75Testsuites.......................79Thetestframeworkcode...81
Debuggingtechniques.................87Tracemacros...................87Tracefile.........................88Findingmemoryleaks.......90
Summary...................................96Exercises...................................97
II:TheStandardC++Library101
3:StringsinDepth103Whatsinastring?....................104CreatingandinitializingC++strings.............................106Operatingonstrings.................109
Appending,inserting,andconcatenatingstrings......110Replacingstringcharacters......................112Concatenationusingnonmemberoverloadedoperators......117
Searchinginstrings..................117Findinginreverse...........123Findingfirst/lastofasetofcharacters..........124Removingcharactersfromstrings...................126Comparingstrings..........129Stringsandcharactertraits...............134
Astringapplication...................140Summary.................................145Exercises.................................146
4:Iostreams151Whyiostreams?........................151Iostreamstotherescue............156
Insertersandextractors..156Commonusage..............161
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 7/458
Lineorientedinput.........164Handlingstreamerrors..............165Fileiostreams...........................168
AFileProcessingExample........................169Openmodes...................171
Iostreambuffering....................173Seekinginiostreams.................175Stringiostreams.......................179
Inputstringstreams........180Outputstringstreams......182
Outputstreamformatting..........186Formatflags...................186Formatfields..................188Width,fill,andprecision..190Anexhaustiveexample...191
Manipulators.............................194Manipulatorswitharguments.....................196Creatingmanipulators.....199Effectors........................201
Iostreamexamples....................203Maintainingclasslibrarysourcecode...................204Detectingcompilererrors208Asimpledatalogger.......211
Internationalization...................216WideStreams.................216Locales..........................218
Summary.................................221Exercises.................................222
5:TemplatesinDepth227Templateparameters.................227
Nontypetemplateparameters.......228Defaulttemplatearguments.....................230Templatetemplateparameters....................232Thetypenamekeyword...238Usingthetemplatekeywordasahint...........240MemberTemplates.........242
Functiontemplateissues...........245Typedeductionoffunctiontemplatearguments........245Functiontemplateoverloading....................249Takingtheaddressofageneratedfunctiontemplate............251ApplyingafunctiontoanSTLsequence.........255Partialorderingoffunctiontemplates..........259
Templatespecialization...............260Explicitspecialization.......261PartialSpecialization.......263Apracticalexample........265Preventingtemplatecodebloat......................268
Namelookupissues..................273Namesintemplates........273Templatesandfriends.....279
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 8/458
Templateprogrammingidioms....285Traits.............................285Policies..........................291Thecuriouslyrecurringtemplatepattern.............294
Templatemetaprogramming.......297Compiletimeprogramming.................298Expressiontemplates......308
Templatecompilationmodels......315Theinclusionmodel........315Explicitinstantiation........316Theseparationmodel......319
Summary.................................320Exercises.................................321
6:GenericAlgorithms325Afirstlook...............................325
Predicates......................329Streamiterators.............331Algorithmcomplexity......333
Functionobjects.......................335Classificationoffunctionobjects..............336Automaticcreationoffunctionobjects..............338Adaptablefunctionobjects341Morefunctionobjectexamples.............343Functionpointeradaptors351Writingyourownfunctionobjectadaptors..358
AcatalogofSTLalgorithms.......362Supporttoolsforexamplecreation............365Fillingandgenerating......368Counting........................370Manipulatingsequences...372Searchingandreplacing..377Comparingranges..........385Removingelements........389Sortingandoperationsonsortedranges............393Heapoperations.............403Applyinganoperationtoeachelementinarange..405Numericalgorithms.........413Generalutilities..............417
CreatingyourownSTLstylealgorithms.................419Summary.................................420Exercises.................................421
7:GenericContainers429Containersanditerators............429
STLreferencedocumentation................431
Afirstlook...............................432Containersofstrings.......438InheritingfromSTLcontainers................440
Aplethoraofiterators...............442Iteratorsinreversiblecontainers.......445
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 9/458
Iteratorcategories..........446Predefinediterators........448
Thebasicsequences:vector,list,deque.....................454
Basicsequenceoperations454vector............................457deque............................465Convertingbetweensequences......................467Checkedrandomaccess.470list.................................471Swappingsequences.......477
set..........................................479Acompletelyreusabletokenizer..........482
stack.......................................487queue......................................491Priorityqueues.........................496Holdingbits..............................506
bitset.......................507vector.................511
Associativecontainers...............513Generatorsandfillersforassociativecontainers518Themagicofmaps.........521Multimapsandduplicatekeys................523Multisets........................527
CombiningSTLcontainers..........530Cleaningupcontainersofpointers...............534Creatingyourowncontainers.....536STLextensions.........................538NonSTLcontainers..................540Summary.................................546Exercises.................................546
III:SpecialTopics549
8:RuntimeTypeIdentification551Runtimecasts..........................551Thetypeidoperator..................557
Castingtointermediatelevels.........560voidpointers..................561UsingRTTIwithtemplates................562
Multipleinheritance....................563SensibleusesforRTTI...............564
Atrashrecycler..............565MechanismandoverheadofRTTI......................570Summary.................................570Exercises.................................571
9:MultipleInheritance573Perspective...............................573Interfaceinheritance..................575Implementationinheritance........579Duplicatesubobjects.................585Virtualbaseclasses...................589Namelookupissues..................599AvoidingMI..............................603
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 10/458
Extendinganinterface...............603Summary.................................608Exercises.................................609
10:DesignPatterns613Thepatternconcept..................613
Prefercompositiontoinheritance.................615
Classifyingpatterns...................615Features,idioms,patterns.........................616
SimplifyingIdioms.....................617Messenger.....................617CollectingParameter.......618
Singleton.................................619VariationsonSingleton....621
Command:choosingtheoperation...........................626
DecouplingeventhandlingwithCommand...............628
Objectdecoupling.....................631Proxy:frontingforanotherobject................632State:changingobjectbehavior..............634
Adapter...................................636TemplateMethod.......................639Strategy:choosingthealgorithmatruntime..................640ChainofResponsibility:tryingasequenceofstrategies...642Factories:encapsulatingobjectcreation.........................645
Polymorphicfactories......647Abstractfactories............651Virtualconstructors.........654
Builder:creatingcomplexobjects.......................660Observer..................................667
Theinnerclassidiom....671Theobserverexample....674
Multipledispatching...................679MultipledispatchingwithVisitor.....................683
Summary.................................687Exercises.................................688
11:Concurrency691Motivation................................692ConcurrencyinC++..................694
InstallingZThreads.........695DefiningTasks..........................696UsingThreads..........................698
Creatingresponsiveuserinterfaces...............700SimplifyingwithExecutors.......................702Yielding..........................706Sleeping........................707Priority..........................709
Sharinglimitedresources...........711Ensuringtheexistenceofobjects........711Improperlyaccessing
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 11/458
resources.......................715Controllingaccess...........719SimplifiedcodingwithGuards....................721Threadlocalstorage.......724
Terminatingtasks......................727Preventingiostreamcollision.........................727Theornamentalgarden...728Terminatingwhenblocked.................733Interruption....................735
Cooperationbetweenthreads.....741Waitandsignal...............742Producerconsumerrelationships...................747Solvingthreadingproblemswithqueues....................750Broadcast......................757
Deadlock..................................764Summary.................................770Exercises.................................773
A:RecommendedReading777GeneralC++............................777
Brucesbooks.................777Chucksbooks................779
IndepthC++..........................779DesignPatterns........................781
B:Etc783
Index791
IntroductionInVolume1ofthisbook,youlearnedthefundamentalsofCandC++.Inthisvolume,welookatmoreadvancedfeatures,withaneyetowardsdevelopingtechniquesandideasthatproducerobustC++programs.
WeassumeyouarefamiliarwiththematerialpresentedinVolume1.
GoalsOurgoalsinthisbookareto:
1.Presentthematerialasimplestepatatime,sothereadercaneasilydigesteachconceptbeforemovingon.
2.Teachpracticalprogrammingtechniquesthatyoucanuseonadaytodaybasis.
3.Giveyouwhatwethinkisimportantforyoutounderstandaboutthelanguage,ratherthaneverythingweknow.Webelievethereisaninformationimportancehierarchy,andtherearesomefactsthat95%ofprogrammerswillneverneedtoknow,butthatwouldjustconfusepeopleandaddtotheirperceptionofthecomplexityofthelanguage.TotakeanexamplefromC,ifyoumemorizetheoperatorprecedencetable(weneverdid)youcanwriteclevercode.Butifyoumustthinkaboutit,itwillconfusethereader/maintainerofthatcode.Soforgetaboutprecedenceanduse
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 12/458
parentheseswhenthingsarentclear.ThissameattitudewillbetakenwithsomeinformationintheC++language,whichismoreimportantforcompilerwritersthanforprogrammers.
4.Keepeachsectionfocusedenoughsothelecturetimeandthetimebetweenexerciseperiodsissmall.Notonlydoesthiskeeptheaudiencemindsmoreactiveandinvolvedduringahandsonseminar,butitgivesthereaderagreatersenseofaccomplishment.
5.WehaveendeavorednottouseanyparticularvendorsversionofC++.Wehavetestedthecodeonalltheimplementationswecould(describedlaterinthisintroduction),andwhenoneimplementationabsolutelyrefusedtoworkbecauseitdoesntconformtotheC++Standard,weveflaggedthatfactintheexample(youllseetheflagsinthesourcecode)toexcludeitfromthebuildprocess.
6.Automatethecompilingandtestingofthecodeinthebook.Wehavediscoveredthatcodethatisntcompiledandtestedisprobablybroken,sointhisvolumeweveinstrumentedtheexampleswithtestcode.Inaddition,thecodethatyoucandownloadfromhttp://www.MindView.nethasbeenextracteddirectlyfromthetextofthebookusingprogramsthatautomaticallycreatemakefilestocompileandrunthetests.Thiswayweknowthatthecodeinthebookiscorrect.
ChaptersHereisabriefdescriptionofthechapterscontainedinthisbook:
Part1:BuildingStableSystems
1.Exceptionhandling.Errorhandlinghasalwaysbeenaprobleminprogramming.Evenifyoudutifullyreturnerrorinformationorsetaflag,thefunctioncallermaysimplyignoreit.ExceptionhandlingisaprimaryfeatureinC++thatsolvesthisproblembyallowingyoutothrowanobjectoutofyourfunctionwhenacriticalerrorhappens.Youthrowdifferenttypesofobjectsfordifferenterrors,andthefunctioncallercatchestheseobjectsinseparateerrorhandlingroutines.Ifyouthrowanexception,itcannotbeignored,soyoucanguaranteethatsomethingwillhappeninresponsetoyourerror.Thedecisiontouseexceptionsaffectscodedesigninpositive,fundamentalways.
2.DefensiveProgramming.Manysoftwareproblemscanbeprevented.Toprogramdefensivelyistocraftcodeinsuchawaythatbugsarefoundandfixedearlybeforetheycandamageinthefield.Usingassertionsisthesinglemostimportantwaytovalidateyourcodeduringdevelopment,whileatthesametimeleavinganexecutabledocumentationtrailinyourcodethatrevealsyourthoughtswhileyouwrotethecodeinthefirstplace.Rigorouslytestyourcodebeforeyouletoutofyourhands.Anautomatedunittestingframeworkisanindispensabletoolforsuccessful,everydaysoftwaredevelopment.
Part2:TheStandardC++Library
3.StringsinDepth.Themostcommonprogrammingactivityistextprocessing.TheC++stringclassrelievestheprogrammerfrommemorymanagementissues,whileatthesametimedeliveringapowerhouseoftextprocessingcapability.C++alsosupportstheuseofwidecharactersandlocalesforinternationalizedapplications.
4.Iostreams.OneoftheoriginalC++librariestheonethatprovidestheessentialI/Ofacilityiscallediostreams.IostreamsisintendedtoreplaceCsstdio.hwithanI/Olibrarythatiseasiertouse,moreflexible,andextensibleyoucanadaptittoworkwithyournewclasses.ThischapterteachesyouhowtomakethebestuseoftheexistingiostreamlibraryforstandardI/O,fileI/O,andinmemoryformatting.
5.TemplatesinDepth.ThedistinguishingfeatureofmodernC++isthebroadpoweroftemplates.Templatesdomorethanjustcreategenericcontainers.Theysupportdevelopmentofrobust,generic,highperformancelibraries.Thereisalottoknowabouttemplatestheyconstitute,asitwere,asublanguagewithintheC++language,andgivetheprogrammeranimpressivedegreeofcontroloverthecompilationprocess.ItisnotanoverstatementtosaythattemplateshaverevolutionizedC++programming.
6.GenericAlgorithms.Algorithmsareatthecoreofcomputing,andC++,throughitstemplatefacility,supportsanimpressiveentourageofpowerful,efficient,andeasytousegenericalgorithms.Thestandardalgorithmsarealsocustomizablethroughfunctionobjects.Thischapterlooksateveryalgorithminthelibrary.(Chapters6and7coverthatportionoftheStandardC++librarycommonlyknownastheStandardTemplateLibrary,orSTL.)
7.GenericContainers&Iterators.C++supportsallthecommondatastructuresinatypesafemanner.Youneverneedtoworryaboutwhatsuchacontainerholds.Thehomogeneityofitsobjectsisguaranteed.Separatingthetraversingofacontainerfromthecontaineritself,anotheraccomplishmentoftemplates,ismadepossiblethroughiterators.Thisingeniousarrangementallowsaflexibleapplicationof
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 13/458
algorithmstocontainersusingthesimplestofdesigns.
Part3:SpecialTopics
8.Runtimetypeidentification.Runtimetypeidentification(RTTI)findstheexacttypeofanobjectwhenyouonlyhaveapointerorreferencetothebasetype.Normally,youllwanttointentionallyignoretheexacttypeofanobjectandletthevirtualfunctionmechanismimplementthecorrectbehaviorforthattype.Butoccasionally(likewhenwritingsoftwaretoolssuchasdebuggers)itishelpfultoknowtheexacttypeofanobjectwiththisinformation,youcanoftenperformaspecialcaseoperationmoreefficiently.ThischapterexplainswhatRTTIisforandhowtouseit.
9.Multipleinheritance.Thissoundssimpleatfirst:Anewclassisinheritedfrommorethanoneexistingclass.However,youcanendupwithambiguitiesandmultiplecopiesofbaseclassobjects.Thatproblemissolvedwithvirtualbaseclasses,butthebiggerissueremains:Whendoyouuseit?Multipleinheritanceisonlyessentialwhenyouneedtomanipulateanobjectthroughmorethanonecommonbaseclass.Thischapterexplainsthesyntaxformultipleinheritanceandshowsalternativeapproachesinparticular,howtemplatessolveonetypicalproblem.Usingmultipleinheritancetorepairadamagedclassinterfaceisdemonstratedasavaluableuseofthisfeature.
10.DesignPatterns.Themostrevolutionaryadvanceinprogrammingsinceobjectsistheintroductionofdesignpatterns.Adesignpatternisalanguageindependentcodificationofasolutiontoacommonprogrammingproblem,expressedinsuchawaythatitcanapplytomanycontexts.PatternssuchasSingleton,FactoryMethod,andVisitornowfindtheirwayintodailydiscussionsaroundthekeyboard.ThischaptershowshowtoimplementandusesomeofthemoreusefuldesignpatternsinC++.
11.ConcurrentProgramming.Peoplehavecometoexpectresponsiveuserinterfacesthat(seemto)processmultipletaskssimultaneously.Modernoperatingsystemsallowprocessestohavemultiplethreadsthatsharetheprocessaddressspace.Multithreadedprogrammingrequiresadifferentmindset,however,andcomeswithitsownsetofdifficulties.Thischapterusesafreelyavailablelibrary(theZThreadlibrarybyEricCrahenofIBM)toshowhowtoeffectivelymanagemultithreadedapplicationsinC++.
ExercisesWehavediscoveredthatsimpleexercisesareexceptionallyusefulduringaseminartocompleteastudentsunderstanding.Youllfindasetattheendofeachchapter.
Thesearefairlysimple,sotheycanbefinishedinareasonableamountoftimeinaclassroomsituationwhiletheinstructorobserves,makingsureallthestudentsareabsorbingthematerial.Someexercisesareabitmorechallengingtokeepadvancedstudentsentertained.Theyrealldesignedtobesolvedinashorttimeandareonlytheretotestandpolishyourknowledgeratherthanpresentmajorchallenges(presumably,youllfindthoseonyourownormorelikelytheyllfindyou).
ExercisesolutionsSolutionstoexercisescanbefoundintheelectronicdocumentTheC++AnnotatedSolutionGuide,Volume2,availableforanominalfeefromhttp://www.MindView.net.
SourcecodeThesourcecodeforthisbookiscopyrightedfreeware,distributedviathewebsitehttp://www.MindView.net.Thecopyrightpreventsyoufromrepublishingthecodeinprintmediawithoutpermission.
Inthestartingdirectorywhereyouunpackthecodeyouwillfindthefollowingcopyrightnotice:
//:!:CopyRight.txt(c)19952004MindView,Inc.Allrightsreserved.Sourcecodefilefromthebook"ThinkinginC++,2ndEdition,Volume2."Thefollowingpermissionsaregrantedrespectingthecomputersourcecode,whichiscontainedinthisfile:Permissionisgrantedtoclassroomeducatorstousethisfileaspartofinstructionalmaterialspreparedforclassespersonallytaughtorsupervisedbytheeducatorwho
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 14/458
usesthispermission,providedthat(a)thebook"ThinkinginC++"iscitedastheoriginoneachpageorslidethatcontainsanypartofthisfile,and(b)thatyoumaynotremovetheabovecopyrightlegendnorthisnotice.Thispermissionextendstohandouts,slidesandotherpresentationmaterials.Forpurposesthatdonotincludethepublicationorpresentationofeducationalorinstructionalmaterials,permissionalsoisgrantedtocomputerprogramdesignersandprogrammers,andtotheiremployersandcustomers,(a)touseandmodifythisfileforthepurposeofcreatingexecutablecomputersoftware,and(b)todistributeresultingcomputerprogramsinbinaryformonly,providedthat(c)youmaynotremovetheabovecopyrightlegendnorthisnoticefromretainedsourcecodecopiesofthisfile,and(d)eachcopydistributedinbinaryformhasembeddedwithinittheabovecopyrightnotice.Apartfromthepermissionsgrantedabove,thesoleauthorizeddistributionpointforadditionalcopiesofthisfileishttp://www.MindView.net(andofficialmirrorsites)whereitisavailable,subjecttothepermissionsandrestrictionssetforthherein.Thefollowingareclarificationsofthelimitedpermissionsgrantedabove:1.Youmaynotpublishordistributeoriginalsormodifiedversionsofthesourcecodetothesoftwareotherthaninclassroomsituationsdescribedabove.2.Youmaynotusethesoftwarefileorportionsthereofinprintedmediawithouttheexpresspermissionofthecopyrightowner.Thecopyrightownerandauthororauthorsmakenorepresentationaboutthesuitabilityofthissoftwareforanypurpose.Itisprovided"asis,"andallexpress,implied,andstatutorywarrantiesandconditionsofanykindincludinganywarrantiesandconditionsofmerchantability,satisfactoryquality,security,fitnessforaparticularpurposeandnoninfringement,aredisclaimed.Theentireriskastothequalityandperformanceofthesoftwareiswithyou.Innoeventwilltheauthorsorthepublisherbeliableforanylostrevenue,savings,ordata,orfordirect,indirect,special,consequential,incidental,exemplaryorpunitivedamages,howevercausedandregardlessofanyrelatedtheoryofliability,arisingoutofthislicenseand/ortheuseoforinabilitytousethissoftware,evenifthevendorsand/orthepublisherhavebeenadvisedofthepossibilityofsuchdamages.Shouldthesoftwareprovedefective,youassumethecostofallnecessaryservicing,repair,orcorrection.Ifyouthinkyouhaveacorrectionforanerrorinthesoftware,pleasesubmitthecorrectiontowww.MindView.net.(Pleaseusethesameprocessfornoncodeerrorsfoundinthebook.)Ifyouhaveaneedforpermissionsnotgrantedabove,pleaseinquireofMindView,Inc.,[email protected].///:~
Youmayusethecodeinyourprojectsandintheclassroomaslongasthecopyrightnoticeisretained.
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 15/458
CompilersYourcompilermaynotsupportallthefeaturesdiscussedinthisbook,especiallyifyoudonthavethenewestversionofyourcompiler.ImplementingalanguagelikeC++isaHerculeantask,andyoucanexpectthatthefeatureswillappearinpiecesratherthanallatonce.Butifyouattemptoneoftheexamplesinthebookandgetalotoferrorsfromthecompiler,itsnotnecessarilyabuginthecodeorthecompileritmaysimplynotbeimplementedinyourparticularcompileryet.
Weusedanumberofcompilerstotestthecodeinthisbook,inanattempttoensurethatourcodeconformstotheC++Standardandwillworkwithasmanycompilersaspossible.Unfortunately,notallcompilersconformtotheC++Standard,andsowehaveawayofexcludingcertainfilesfrombuildingwiththosecompilers.Theseexclusionsarereflectedinthemakefilesautomaticallycreatedforthepackageofcodeforthisbookthatyoucandownloadfromwww.MindView.net.Youcanseetheexclusiontagsembeddedinthecommentsatthebeginningofeachlisting,soyouwillknowwhethertoexpectaparticularcompilertoworkonthatcode(inafewcases,thecompilerwillactuallycompilethecodebuttheexecutionbehavioriswrong,andweexcludethoseaswell).
Herearethetagsandthecompilersthattheyexcludefromthebuild:
{dmc}WalterBrightsDigitalMarscompilerforWindows,freelydownloadableatwww.DigitalMars.com.Thiscompilerisveryconformantandsoyouwillseealmostnoneofthesetagsthroughoutthebook.
{g++}ThefreeGnuC++3.3.1,whichcomespreinstalledinmostLinuxpackagesandMacintoshOSX.ItisalsopartofCygwinforWindows(seebelow).Itisavailableformostotherplatformsfromgcc.gnu.org.
{msc}MicrosoftVersion7withVisualC++.NET(onlycomeswithVisualStudio.NETnotfreelydownloadable).
{bor}BorlandC++Version6(notthefreedownloadthisoneismoreuptodate).
{edg}EdisonDesignGroup(EDG)C++.Thisisthebenchmarkcompilerforstandardsconformance.Thistagoccursonlybecauseoflibraryissues,andbecausewewereusingacomplimentarycopyoftheEDGfrontendwithacomplimentarylibraryimplementationfromDinkumware,Ltd.Nocompileerrorsoccurredbecauseofthecompileralone.
{mwcc}MetrowerksCodeWarriorforMacintoshOSX.NotethatOSXcomeswithGnuC++preinstalled,aswell.
Ifyoudownloadandunpackthecodepackageforthisbookfromwww.MindView.net,youllfindthemakefilestobuildthecodefortheabovecompilers.WeusedthefreelyavailableGNUmake,whichcomeswithLinux,Cygwin(afreeUnixshellthatrunsontopofWindowsseewww.Cygwin.com),orcanbeinstalledonyourplatformseewww.gnu.org/software/make.(Othermakesmayormaynotworkwiththesefiles,butarenotsupported.)Onceyouinstallmake,ifyoutypemakeatthecommandlineyoullgetinstructionsonhowtobuildthebookscodefortheabovecompilers.
Notethattheplacementofthesetagsonthefilesinthisbookindicatesthestateoftheparticularversionofthecompileratthetimewetriedit.Itspossibleandlikelythatthecompilervendorhasimprovedthecompilersincethepublicationofthisbook.Itsalsopossiblethatwhilebuildingthebookwithsomanycompilers,wemayhavemisconfiguredaparticularcompilerthatwouldotherwisehavecompiledthecodecorrectly.Thus,youshouldtrythecodeyourselfonyourcompiler,andalsocheckthecodedownloadedfromwww.MindView.nettoseewhatiscurrent.
LanguagestandardsThroughoutthisbook,whenreferringtoconformancetotheANSI/ISOCstandard,wewillbereferringtothe1989standard,andwillgenerallyjustsayC.OnlyifitisnecessarytodistinguishbetweenStandard1989Candolder,preStandardversionsofCwillwemakethedistinction.WedonotreferenceC99inthisbook.
TheANSI/ISOC++CommitteelongagofinishedworkingonthefirstC++Standard,commonlyknownasC++98.WewillusethetermStandardC++torefertothisstandardizedlanguage.IfwesimplyrefertoC++,assumewemeanStandardC++.TheC++StandardsCommitteecontinuestoaddressissuesimportanttotheC++communitythatwillbecomeC++0x,afutureC++Standardnotlikelytobeavailableformanyyears.
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 16/458
Seminars,CDROMs&consultingBruceEckelscompany,MindView,Inc.,providespublichandsontrainingseminarsbasedonthematerialinthisbook,andalsoforadvancedtopics.Selectedmaterialfromeachchapterrepresentsalesson,whichisfollowedbyamonitoredexerciseperiodsoeachstudentreceivespersonalattention.Wealsoprovideonsitetraining,consulting,mentoring,anddesign&codewalkthroughs.Informationandsignupformsforupcomingseminarsandothercontactinformationisfoundathttp://www.MindView.net.
ErrorsNomatterhowmanytrickswritersusetodetecterrors,somealwayscreepinandtheseoftenleapoffthepageforafreshreader.Ifyoudiscoveranythingyoubelievetobeanerror,pleaseusethefeedbacksystembuiltintotheelectronicversionofthisbook,whichyouwillfindathttp://www.MindView.net.Yourhelpisappreciated.
AboutthecoverThecoverartworkwaspaintedbyLarryOBrienswife,TinaJensen(yes,theLarryOBrienwhowastheeditorofSoftwareDevelopmentMagazineforsomanyyears).Notonlyarethepicturesbeautiful,theyarealsoexcellentsuggestionsofpolymorphism.TheideaforusingtheseimagescamefromDanielWillHarris,thecoverdesigner(www.WillHarris.com),workingwithBruce.
AcknowledgementsVolume2ofthisbooklanguishedinahalfcompletedstateforalongtimewhileBrucegotdistractedwithotherthings,notablyJava,DesignPatternsandespeciallyPython(seewww.Python.org).IfChuckhadntbeenwilling(foolishly,hehassometimesthought)tofinishtheotherhalfandbringthingsuptodate,thisbookalmostcertainlywouldnthavehappened.TherearentthatmanypeoplewhomBrucewouldhavefeltcomfortableentrustingthisbookto.Chuckspenchantforprecision,correctnessandclearexplanationiswhathasmadethisbookasgoodasitis.
JamieKingactedasaninternunderChucksdirectionduringthecompletionofthisbook.Hewasanessentialpartofmakingsurethebookgotfinished,notonlybyprovidingfeedbackforChuck,butespeciallybecauseofhisrelentlessquestioningandpickingofeverysinglepossiblenitthathedidntcompletelyunderstand.Ifyourquestionsareansweredbythisbook,itsprobablybecauseJamieaskedthemfirst.Jamiealsoenhancedanumberofthesampleprogramsandcreatedmanyoftheexercisesattheendofeachchapter.ScottBaker,anotherofChucksinternsfundedbyMindView,Inc.,helpedwiththeexercisesforChapter3.
EricCrahenofIBMwasinstrumentalinthecompletionofChapter11(Concurrency).Whenwewerelookingforathreadspackage,wesoughtoutonethatwasintuitiveandeasytouse,whilebeingsufficientlyrobusttodothejob.WithEricwegotthatandthensomehewasextremelycooperativeandhasusedourfeedbacktoenhancehislibrary,whilewehavebenefitedfromhisinsightsaswell.
WearegratefultoPeteBeckerforbeingourtechnicaleditor.FewpeopleareasarticulateanddiscriminatingasPete,nottomentionasexpertinC++andsoftwaredevelopmentingeneral.WealsothankBjornKarlssonforhisgraciousandtimelytechnicalassistanceashereviewedtheentiremanuscriptwithshortnotice.
WalterBrightmadeHerculeaneffortstomakesurethathisDigitalMarsC++compilerwouldcompiletheexamplesinthisbook.Hemakesthecompileravailableforfreedownloadsathttp://www.DigitalMars.com.Thanks,Walter!
Theideasandunderstandinginthisbookhavecomefrommanyothersources,aswell:friendslikeAndreaProvaglio,DanSaks,ScottMeyers,CharlesPetzold,andMichaelWilkpioneersofthelanguagelikeBjarneStroustrup,AndrewKoenig,andRobMurraymembersoftheC++StandardsCommitteelikeNathanMyers(whowasparticularlyhelpfulandgenerouswithhisinsights),HerbSutter,PJPlauger,KevlinHenney,DavidAbrahams,TomPlum,RegCharney,TomPenello,SamDruker,UweSteinmueller,JohnSpicer,SteveAdamczyk,andDaveedVandevoordepeoplewhohavespokenintheC++trackattheSoftwareDevelopmentConference(whichBrucecreatedanddeveloped,andChuckspokein)ColleaguesofChucklikeMichaelSeaver,HustonFranklin,DavidWagstaff,andoftenstudentsinseminars,whoaskthequestionsweneedtoheartomakethematerialclearer.
Thebookdesign,typefaceselection,coverdesign,andcoverphotowerecreatedbyBrucesfriendDanielWillHarris,notedauthoranddesigner,whousedtoplaywithrubonlettersinjuniorhighschoolwhileheawaitedtheinventionofcomputersanddesktoppublishing.However,weproducedthecameraready
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 17/458
pagesourselves,sothetypesettingerrorsareours.MicrosoftWordXPwasusedtowritethebookandtocreatecamerareadypages.ThebodytypefaceisVerdanaandtheheadlinesareinVerdana.ThecodetypefaceisCourierNew.
WealsowishtothankthegenerousprofessionalsattheEdisonDesignGroupandDinkumware,Ltd.,forgivinguscomplimentarycopiesoftheircompilerandlibrary(respectively).Withouttheirexpertassistance,graciouslygiven,someoftheexamplesinthisbookcouldnothavebeentested.WealsowishtothankHowardHinnantandthefolksatMetrowerksforacopyoftheircompiler,andSandySmithandthefolksatSlickEditforkeepingChucksuppliedwithaworldclasseditingenvironmentforsomanyyears.GregComeaualsoprovidedacopyofhissuccessfulEDGbasedcompiler,ComeauC++.
Aspecialthankstoallourteachers,andallourstudents(whoareourteachersaswell).
EvanCofsky([email protected])providedallsortsofassistanceontheserveraswellasdevelopmentofprogramsinhisnowfavoritelanguage,Python.SharlynnCobaughandPaulaSteuerwereinstrumentalassistants,preventingBrucefrombeingwashedawayinafloodofprojects.
BrucessweetieDawnMcGeeprovidedmuchappreciatedinspirationandenthusiasmduringthisproject.Thesupportingcastoffriendsincludes,butisnotlimitedto:MarkWestern,GenKiyooka,KraigBrockschmidt,ZackUrlocker,AndrewBinstock,NeilRubenking,SteveSinofsky,JDHildebrandt,BrianMcElhinney,BrinkleyBarr,BillGatesatMidnightEngineeringMagazine,LarryConstantine&LucyLockwood,TomKeffer,GregPerry,DanPutterman,ChristiWestphal,GeneWang,DaveMayer,DavidIntersimone,ClaireSawyers,TheItalians(AndreaProvaglio,LauraFallai,MarcoCantu,Corrado,IlsaandChristinaGiustozzi),Chris&LauraStrand,TheAlmquists,BradJerbic,JohnKruth&MarilynCvitanic,HollyPayne(yes,thefamousnovelist!),MarkMabry,TheRobbinsFamilies,TheMoelterFamilies(&theMcMillans),TheWilks,DaveStoner,LaurieAdams,TheCranstons,LarryFogg,Mike&KarenSequeira,GaryEntsminger&AllisonBrody,ChesterAndersen,JoeLordi,Dave&BrendaBartlett,TheRentschlers,TheSudeks,Lynn&Todd,andtheirfamilies.Andofcourse,Mom&Dad,Sandy,James&Natalie,Kim&Jared,Isaac,andAbbi.
Part1:BuildingStableSystemsSoftwareengineersspendaboutasmuchtimevalidatingcodeastheydocreatingit.Qualityisorshouldbethegoalofeveryprogrammer,andonecangoalongwaytowardsthatgoalbyeliminatingproblemsbeforetheyhappen.Inaddition,softwaresystemsshouldberobustenoughtobehavereasonablyinthepresenceofunforeseenenvironmentalproblems.
ExceptionswereintroducedintoC++tosupportsophisticatederrorhandlingwithoutclutteringcodewithaninordinateamountoferrorhandlinglogic.Chapter1showshowproperuseofexceptionscanmakeforwellbehavedsoftware,andalsointroducesthedesignprinciplesthatunderlieexceptionsafecode.InChapter2wecoverunittestinganddebuggingtechniquesintendedtomaximizecodequalitylongbeforeitsreleased.Theuseofassertionstoexpressandenforceprograminvariantsisasuresignofanexperiencedsoftwareengineer.Wealsointroduceasimpleframeworktosupportunittesting.
1:ExceptionHandlingImprovingerrorrecoveryisoneofthemostpowerfulwaysyoucanincreasetherobustnessofyourcode.
Unfortunately,itsalmostacceptedpracticetoignoreerrorconditions,asifwereinastateofdenialabouterrors.Onereason,nodoubt,isthetediousnessandcodebloatofcheckingformanyerrors.Forexample,printf()returnsthenumberofcharactersthatweresuccessfullyprinted,butvirtuallynoonechecksthisvalue.Theproliferationofcodealonewouldbedisgusting,nottomentionthedifficultyitwouldaddin
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 18/458
readingthecode.
TheproblemwithCsapproachtoerrorhandlingcouldbethoughtofascouplingtheuserofafunctionmusttietheerrorhandlingcodesocloselytothatfunctionthatitbecomestooungainlyandawkwardtouse.
OneofthemajorfeaturesinC++isexceptionhandling,whichisabetterwayofthinkingaboutandhandlingerrors.Withexceptionhandling:
1.Errorhandlingcodeisnotnearlysotedioustowrite,anditdoesntbecomemixedupwithyournormalcode.Youwritethecodeyouwanttohappenlaterinaseparatesectionyouwritethecodetocopewiththeproblems.Ifyoumakemultiplecallstoafunction,youhandletheerrorsfromthatfunctiononce,inoneplace.
2.Errorscannotbeignored.Ifafunctionneedstosendanerrormessagetothecallerofthatfunction,itthrowsanobjectrepresentingthaterroroutofthefunction.Ifthecallerdoesntcatchtheerrorandhandleit,itgoestothenextenclosingdynamicscope,andsoonuntiltheerroriseithercaughtortheprogramterminatesbecausetherewasnohandlertocatchthattypeofexception.
ThischapterexaminesCsapproachtoerrorhandling(suchasitis),discusseswhyitdidnotworkwellforC,andexplainswhyitwontworkatallforC++.Thischapteralsocoverstry,throw,andcatch,theC++keywordsthatsupportexceptionhandling.
TraditionalerrorhandlingInmostoftheexamplesinthesevolumes,weuseassert()asitwasintended:fordebuggingduringdevelopmentwithcodethatcanbedisabledwith#defineNDEBUGfortheshippingproduct.Runtimeerrorcheckingusestherequire.hfunctions(assure()andrequire())developedinChapter9inVolume1andrepeatedhereinAppendixB.Thesefunctionsareaconvenientwaytosay,Theresaproblemhereyoullprobablywanttohandlewithsomemoresophisticatedcode,butyoudontneedtobedistractedbyitinthisexample.Therequire.hfunctionsmightbeenoughforsmallprograms,butforcomplicatedproductsyoullwanttowritemoresophisticatederrorhandlingcode.
Errorhandlingisquitestraightforwardwhenyouknowexactlywhattodo,becauseyouhaveallthenecessaryinformationinthatcontext.Youcanjusthandletheerroratthatpoint.
Theproblemoccurswhenyoudonthaveenoughinformationinthatcontext,andyouneedtopasstheerrorinformationintoadifferentcontextwherethatinformationdoesexist.InC,youcanhandlethissituationusingthreeapproaches:
1.Returnerrorinformationfromthefunctionor,ifthereturnvaluecannotbeusedthisway,setaglobalerrorconditionflag.(StandardCprovideserrnoandperror()tosupportthis.)Asmentionedearlier,theprogrammerislikelytoignoretheerrorinformationbecausetediousandobfuscatingerrorcheckingmustoccurwitheachfunctioncall.Inaddition,returningfromafunctionthathitsanexceptionalconditionmightnotmakesense.
2.UsethelittleknownStandardClibrarysignalhandlingsystem,implementedwiththesignal()function(todeterminewhathappenswhentheeventoccurs)andraise()(togenerateanevent).Again,thisapproachinvolveshighcouplingbecauseitrequirestheuserofanylibrarythatgeneratessignalstounderstandandinstalltheappropriatesignalhandlingmechanism.Inlargeprojectsthesignalnumbersfromdifferentlibrariesmightclash.
3.UsethenonlocalgotofunctionsintheStandardClibrary:setjmp()andlongjmp().Withsetjmp()yousaveaknowngoodstateintheprogram,andifyougetintotrouble,longjmp()willrestorethatstate.Again,thereishighcouplingbetweentheplacewherethestateisstoredandtheplacewheretheerroroccurs.
WhenconsideringerrorhandlingschemeswithC++,theresanadditionalcriticalproblem:TheCtechniquesofsignalsandsetjmp()/longjmp()donotcalldestructors,soobjectsarentproperlycleanedup.(Infact,iflongjmp()jumpspasttheendofascopewheredestructorsshouldbecalled,thebehavioroftheprogramisundefined.)Thismakesitvirtuallyimpossibletoeffectivelyrecoverfromanexceptionalconditionbecauseyoullalwaysleaveobjectsbehindthathaventbeencleanedupandthatcannolongerbeaccessed.Thefollowingexampledemonstratesthiswithsetjmp/longjmp:
//:C01:Nonlocal.cpp//setjmp()&longjmp().#include
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 19/458
#includeusingnamespacestdclassRainbow{public:Rainbow(){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 20/458
}///:~
MyErrorisanordinaryclass,whichinthiscasetakesachar*asaconstructorargument.Youcanuseanytypewhenyouthrow(includingbuiltintypes),butusuallyyoullcreatespecialclassesforthrowingexceptions.
Thekeywordthrowcausesanumberofrelativelymagicalthingstohappen.First,itcreatesacopyoftheobjectyourethrowingand,ineffect,returnsitfromthefunctioncontainingthethrowexpression,eventhoughthatobjecttypeisntnormallywhatthefunctionisdesignedtoreturn.Anaivewaytothinkaboutexceptionhandlingisasanalternatereturnmechanism(althoughyoullfindyoucangetintotroubleifyoutakethatanalogytoofar).Youcanalsoexitfromordinaryscopesbythrowinganexception.Inanycase,avalueisreturned,andthefunctionorscopeexits.
Anysimilaritytoareturnstatementendstherebecausewhereyoureturnissomeplacecompletelydifferentfromwhereanormalfunctioncallreturns.(Youendupinanappropriatepartofthecodecalledanexceptionhandlerthatmightbefarremovedfromwheretheexceptionwasthrown.)Inaddition,anylocalobjectscreatedbythetimetheexceptionoccursaredestroyed.Thisautomaticcleanupoflocalobjectsisoftencalledstackunwinding.
Inaddition,youcanthrowasmanydifferenttypesofobjectsasyouwant.Typically,youllthrowadifferenttypeforeachcategoryoferror.Theideaistostoretheinformationintheobjectandinthenameofitsclasssothatsomeoneinacallingcontextcanfigureoutwhattodowithyourexception.
CatchinganexceptionAsmentionedearlier,oneoftheadvantagesofC++exceptionhandlingisthatyoucanconcentrateontheproblemyouretryingtosolveinoneplace,andthendealwiththeerrorsfromthatcodeinanotherplace.
ThetryblockIfyoureinsideafunctionandyouthrowanexception(oracalledfunctionthrowsanexception),thefunctionexitsbecauseofthethrownexception.Ifyoudontwantathrowtoleaveafunction,youcansetupaspecialblockwithinthefunctionwhereyoutrytosolveyouractualprogrammingproblem(andpotentiallygenerateexceptions).Thisblockiscalledthetryblockbecauseyoutryyourvariousfunctioncallsthere.Thetryblockisanordinaryscope,precededbythekeywordtry:
try{//Codethatmaygenerateexceptions}
Ifyoucheckforerrorsbycarefullyexaminingthereturncodesfromthefunctionsyouuse,youneedtosurroundeveryfunctioncallwithsetupandtestcode,evenifyoucallthesamefunctionseveraltimes.Withexceptionhandling,youputeverythinginatryblockandhandleexceptionsafterthetryblock.Thus,yourcodeisaloteasiertowriteandtoreadbecausethegoalofthecodeisnotconfusedwiththeerrorhandling.
ExceptionhandlersOfcourse,thethrownexceptionmustendupsomeplace.Thisplaceistheexceptionhandler,andyouneedoneexceptionhandlerforeveryexceptiontypeyouwanttocatch.However,polymorphismalsoworksforexceptions,sooneexceptionhandlercanworkwithanexceptiontypeandclassesderivedfromthattype.
Exceptionhandlersimmediatelyfollowthetryblockandaredenotedbythekeywordcatch:
try{//Codethatmaygenerateexceptions}catch(type1id1){//Handleexceptionsoftype1}catch(type2id2){//Handleexceptionsoftype2}catch(type3id3)//Etc...}catch(typeNidN)//HandleexceptionsoftypeN}//Normalexecutionresumeshere...
Thesyntaxofacatchclauseresemblesfunctionsthattakeasingleargument.Theidentifier(id1,id2,and
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 21/458
soon)canbeusedinsidethehandler,justlikeafunctionargument,althoughyoucanomittheidentifierifitsnotneededinthehandler.Theexceptiontypeusuallygivesyouenoughinformationtodealwithit.
Thehandlersmustappeardirectlyafterthetryblock.Ifanexceptionisthrown,theexceptionhandlingmechanismgoeshuntingforthefirsthandlerwithanargumentthatmatchesthetypeoftheexception.Itthenentersthatcatchclause,andtheexceptionisconsideredhandled.(Thesearchforhandlersstopsoncethecatchclauseisfound.)Onlythematchingcatchclauseexecutescontrolthenresumesafterthelasthandlerassociatedwiththattryblock.
Noticethat,withinthetryblock,anumberofdifferentfunctioncallsmightgeneratethesametypeofexception,butyouneedonlyonehandler.
Toillustratetryandcatch,thefollowingvariationofNonlocal.cppreplacesthecalltosetjmp()withatryblockandreplacesthecalltolongjmp()withathrowstatement:
//:C01:Nonlocal2.cpp//Illustratesexceptions.#includeusingnamespacestdclassRainbow{public:Rainbow(){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 22/458
exceptionisgeneratedfrommanypoints.
ExceptionmatchingWhenanexceptionisthrown,theexceptionhandlingsystemlooksthroughthenearesthandlersintheordertheyappearinthesourcecode.Whenitfindsamatch,theexceptionisconsideredhandledandnofurthersearchingoccurs.
Matchinganexceptiondoesntrequireaperfectcorrelationbetweentheexceptionanditshandler.Anobjectorreferencetoaderivedclassobjectwillmatchahandlerforthebaseclass.(However,ifthehandlerisforanobjectratherthanareference,theexceptionobjectisslicedtruncatedtothebasetypeasitispassedtothehandler.Thisdoesnodamage,butlosesallthederivedtypeinformation.)Forthisreason,aswellastoavoidmakingyetanothercopyoftheexceptionobject,itisalwaysbettertocatchanexceptionbyreferenceinsteadofbyvalue. Ifapointeristhrown,theusualstandardpointerconversionsareusedtomatchtheexception.However,noautomatictypeconversionsareusedtoconvertfromoneexceptiontypetoanotherintheprocessofmatching.Forexample:
//:C01:Autoexcp.cpp//Nomatchingconversions.#includeusingnamespacestdclassExcept1{}classExcept2{public:Except2(constExcept1&){}}voidf(){throwExcept1()}intmain(){try{f()}catch(Except2&){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 23/458
}catch(X::Big&){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 24/458
Whenabort()iscalled,nocallstonormalprogramterminationfunctionsoccur,whichmeansthatdestructorsforglobalandstaticobjectsdonotexecute.Theterminate()functionalsoexecutesifadestructorforalocalobjectthrowsanexceptionwhilethestackisunwinding(interruptingtheexceptionthatwasinprogress)orifaglobalorstaticobjectsconstructorordestructorthrowsanexception.(Ingeneral,donotallowadestructortothrowanexception.)
Theset_terminate()functionYoucaninstallyourownterminate()functionusingthestandardset_terminate()function,whichreturnsapointertotheterminate()functionyouarereplacing(whichwillbethedefaultlibraryversionthefirsttimeyoucallit),soyoucanrestoreitlaterifyouwant.Yourcustomterminate()musttakenoargumentsandhaveavoidreturnvalue.Inaddition,anyterminate()handleryouinstallmustnotreturnorthrowanexception,butinsteadmustexecutesomesortofprogramterminationlogic.Ifterminate()iscalled,theproblemisunrecoverable.
Thefollowingexampleshowstheuseofset_terminate().Here,thereturnvalueissavedandrestoredsothattheterminate()functioncanbeusedtohelpisolatethesectionofcodewheretheuncaughtexceptionoccurs:
//:C01:Terminator.cpp//Useofset_terminate().Alsoshowsuncaughtexceptions.#include#includeusingnamespacestdvoidterminator(){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 25/458
exceptionwasthrown.C++exceptionhandlingguaranteesthatasyouleaveascope,allobjectsinthatscopewhoseconstructorshavebeencompletedwillhavetheirdestructorscalled.
Heresanexamplethatdemonstratesthatconstructorsthatarentcompleteddonthavetheassociateddestructorscalled.Italsoshowswhathappenswhenanexceptionisthrowninthemiddleofthecreationofanarrayofobjects:
//:C01:Cleanup.cpp//Exceptionscleanupcompleteobjectsonly.#includeusingnamespacestdclassTrace{staticintcounterintobjidpublic:Trace(){objid=counter++cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 26/458
Thedifficultyisinallocatingresourcesinconstructors.Ifanexceptionoccursintheconstructor,thedestructordoesntgetachancetodeallocatetheresource.Thisproblemoccursmostoftenwithnakedpointers.Forexample:
//:C01:Rawp.cpp//Nakedpointers.#include#includeusingnamespacestdclassCat{public:Cat(){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 27/458
Topreventsuchresourceleaks,youmustguardagainsttheserawresourceallocationsinoneoftwoways:
Youcancatchexceptionsinsidetheconstructorandthenreleasetheresource.
Youcanplacetheallocationsinsideanobjectsconstructor,andyoucanplacethedeallocationsinsideanobjectsdestructor.
Usingthelatterapproach,eachallocationbecomesatomic,byvirtueofbeingpartofthelifetimeofalocalobject,andifitfails,theotherresourceallocationobjectsareproperlycleanedupduringstackunwinding.ThistechniqueiscalledResourceAcquisitionIsInitialization(RAIIforshort)becauseitequatesresourcecontrolwithobjectlifetime.Usingtemplatesisanexcellentwaytomodifythepreviousexampletoachievethis:
//:C01:Wrapped.cpp//Safe,atomicpointers.#include#includeusingnamespacestd//Simplified.Yoursmayhaveotherarguments.templateclassPWrap{T*ptrpublic:classRangeError{}//ExceptionclassPWrap(){ptr=newT[sz]cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 28/458
UseResourcesur}catch(int){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 29/458
}intmain(){auto_ptrpMyObject(newTraceHeap(5))cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 30/458
toreturntothecodethatcreatedit.Forthisreason,theonlysensiblethingtodoistothrowanexceptioninthefunctionlevelcatchclause.
Althoughitisnotterriblyuseful,C++alsoallowsfunctionleveltryblocksforanyfunction,asthefollowingexampleillustrates:
//:C01:FunctionTryBlock.cpp{bor}//Functionleveltryblocks.//{RunByHand}(Dontrunautomaticallybythemakefile)#includeusingnamespacestdintmain()try{throw"main"}catch(constchar*msg){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 31/458
initialized.
logic_error Derivedfromexception.Reportsprogramlogicerrors,whichcouldpresumablybedetectedbyinspection.
runtime_error Derivedfromexception.Reportsruntimeerrors,whichcanpresumablybedetectedonlywhentheprogramexecutes.
Theiostreamexceptionclassios::failureisalsoderivedfromexception,butithasnofurthersubclasses.
Youcanusetheclassesinbothofthefollowingtablesastheyare,oryoucanusethemasbaseclassesfromwhichtoderiveyourownmorespecifictypesofexceptions.
Exceptionclassesderivedfromlogic_error
domain_error Reportsviolationsofaprecondition.
invalid_argument Indicatesaninvalidargumenttothefunctionfromwhichitisthrown.
length_error Indicatesanattempttoproduceanobjectwhoselengthisgreaterthanorequaltonpos(thelargestrepresentablevalueofcontextssizetype,usuallystd::size_t).
out_of_range Reportsanoutofrangeargument.
bad_cast Thrownforexecutinganinvaliddynamic_castexpressioninruntimetypeidentification(seeChapter8).
bad_typeid Reportsanullpointerpinanexpressiontypeid(*p).(Again,aruntimetypeidentificationfeatureinChapter8).
Exceptionclassesderivedfromruntime_error
range_error Reportsviolationofapostcondition.
overflow_error Reportsanarithmeticoverflow.
bad_alloc Reportsafailuretoallocatestorage.
ExceptionspecificationsYourenotrequiredtoinformthepeopleusingyourfunctionwhatexceptionsyoumightthrow.However,failuretodosocanbeconsidereduncivilizedbecauseitmeansthatuserscannotbesurewhatcodetowritetocatchallpotentialexceptions.Iftheyhaveyoursourcecode,theycanhuntthroughandlookforthrowstatements,butoftenalibrarydoesntcomewithsources.Gooddocumentationcanhelpalleviatethisproblem,buthowmanysoftwareprojectsarewelldocumented?C++providessyntaxtotelltheusertheexceptionsthatarethrownbythisfunction,sotheusercanhandlethem.Thisistheoptionalexceptionspecification,whichadornsafunctionsdeclaration,appearingaftertheargumentlist.
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 32/458
Theexceptionspecificationreusesthekeywordthrow,followedbyaparenthesizedlistofallthetypesofpotentialexceptionsthatthefunctioncanthrow.Yourfunctiondeclarationmightlooklikethis:
voidf()throw(toobig,toosmall,divzero)
Asfarasexceptionsareconcerned,thetraditionalfunctiondeclaration
voidf()
meansthatanytypeofexceptioncanbethrownfromthefunction.Ifyousay
voidf()throw()
noexceptionswhatsoeverwillbethrownfromthefunction(soyoudbetterbesurethatnofunctionsfartherdowninthecallchainletanyexceptionspropagateup!).
Forgoodcodingpolicy,gooddocumentation,andeaseofuseforthefunctioncaller,considerusingexceptionspecificationswhenyouwritefunctionsthatthrowexceptions.(Variationsonthisguidelinearediscussedlaterinthischapter.)
Theunexpected()functionIfyourexceptionspecificationclaimsyouregoingtothrowacertainsetofexceptionsandthenyouthrowsomethingthatisntinthatset,whatsthepenalty?Thespecialfunctionunexpected()iscalledwhenyouthrowsomethingotherthanwhatappearsintheexceptionspecification.Shouldthisunfortunatesituationoccur,thedefaultunexpected()callstheterminate()functiondescribedearlierinthischapter.
Theset_unexpected()functionLiketerminate(),theunexpected()mechanisminstallsyourownfunctiontorespondtounexpectedexceptions.Youdosowithafunctioncalledset_unexpected(),which,likeset_terminate(),takestheaddressofafunctionwithnoargumentsandvoidreturnvalue.Also,becauseitreturnsthepreviousvalueoftheunexpected()pointer,youcansaveitandrestoreitlater.Touseset_unexpected(),includetheheaderfile.Heresanexamplethatshowsasimpleuseofthefeaturesdiscussedsofarinthissection:
//:C01:Unexpected.cpp//Exceptionspecifications&unexpected(),//{msc}(Doesntterminateproperly)#include#includeusingnamespacestdclassUp{}classFit{}voidg()voidf(inti)throw(Up,Fit){switch(i){case1:throwUp()case2:throwFit()}g()}//voidg(){}//Version1voidg(){throw47}//Version2voidmy_unexpected(){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 33/458
}catch(Fit){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 34/458
//thecompilerdetectstheviolationandreports//anerror,soweputitinitsownfunction.voidt(){throwB()}voidf()throw(A){t()}voidg()throw(A,bad_exception){t()}intmain(){set_terminate(my_thandler)set_unexpected(my_uhandler1)try{f()}catch(A&){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 35/458
classesotherwisetheexpectedisarelationshipbetweenderivedandbaseclassesisviolated.Sinceexceptionspecificationsarelogicallypartofafunctionsdeclaration,theytoomustremainconsistentacrossaninheritancehierarchy.Forexample,ifamemberfunctioninabaseclasssaysitwillonlythrowanexceptionoftypeA,anoverrideofthatfunctioninaderivedclassmustnotaddanyotherexceptiontypestothespecificationlistbecausethatwouldbreakanyprogramsthatadheretothebaseclassinterface.Youcan,however,specifyfewerexceptionsornoneatall,sincethatdoesntrequiretheusertodoanythingdifferently.YoucanalsospecifyanythingthatisaAinplaceofAinthederivedfunctionsspecification.Heresanexample.
//:C01:Covariance.cpp{xo}//Shouldcausecompileerror.{mwcc}{msc}#includeusingnamespacestdclassBase{public:classBaseException{}classDerivedException:publicBaseException{}virtualvoidf()throw(DerivedException){throwDerivedException()}virtualvoidg()throw(BaseException){throwBaseException()}}classDerived:publicBase{public:voidf()throw(BaseException){throwBaseException()}virtualvoidg()throw(DerivedException){throwDerivedException()}}///:~
AcompilershouldflagtheoverrideofDerived::f()withanerror(oratleastawarning)sinceitchangesitsexceptionspecificationinawaythatviolatesthespecificationofBase::f().ThespecificationforDerived::g()isacceptablebecauseDerivedExceptionisaBaseException(nottheotherwayaround).YoucanthinkofBase/DerivedandBaseException/DerivedExceptionasparallelclasshierarchieswhenyouareinDerived,youcanreplacereferencestoBaseExceptioninexceptionspecificationsandreturnvalueswithDerivedException.Thisbehavioriscalledcovariance(sincebothsetsofclassesvarydowntheirrespectivehierarchiestogether).(ReminderfromVolume1:parametertypesarenotcovariantyouarenotallowedtochangethesignatureofanoverriddenvirtualfunction.)
WhennottouseexceptionspecificationsIfyouperusethefunctiondeclarationsthroughouttheStandardC++library,youllfindthatnotasingleexceptionspecificationoccursanywhere!Althoughthismightseemstrange,thereisagoodreasonforthisseemingincongruity:thelibraryconsistsmainlyoftemplates,andyouneverknowwhatagenerictypeorfunctionmightdo.Forexample,supposeyouaredevelopingagenericstacktemplateandattempttoaffixanexceptionspecificationtoyourpopfunction,likethis:
Tpop()throw(logic_error)
Sincetheonlyerroryouanticipateisastackunderflow,youmightthinkitssafetospecifyalogic_errororsomeotherappropriateexceptiontype.ButtypeTscopyconstructorcouldthrowanexception.Thenunexpected()wouldbecalled,andyourprogramwouldterminate.Youcantmakeunsupportableguarantees.Ifyoudontknowwhatexceptionsmightoccur,dontuseexceptionspecifications.Thatswhytemplateclasses,whichconstitutethemajorityoftheStandardC++library,donotuseexceptionspecificationstheyspecifytheexceptionstheyknowaboutindocumentationandleavetheresttoyou.Exceptionspecificationsaremainlyfornontemplateclasses.
ExceptionsafetyInChapter7welltakeanindepthlookatthecontainersintheStandardC++library,includingthestackcontainer.Onethingyoullnoticeisthatthedeclarationofthepop()memberfunctionlookslikethis:
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 36/458
voidpop()
Youmightthinkitstrangethatpop()doesntreturnavalue.Instead,itjustremovestheelementatthetopofthestack.Toretrievethetopvalue,calltop()beforeyoucallpop().Thereisanimportantreasonforthisbehavior,andithastodowithexceptionsafety,acrucialconsiderationinlibrarydesign.Therearedifferentlevelsofexceptionsafety,butmostimportantly,andjustasthenameimplies,exceptionsafetyisaboutcorrectsemanticsinthefaceofexceptions.
Supposeyouareimplementingastackwithadynamicarray(wellcallitdataandthecounterintegercount),andyoutrytowritepop()sothatitreturnsavalue.Thecodeforsuchapop()mightlooksomethinglikethis:
templateTstack::pop(){if(count==0)throwlogic_error("stackunderflow")elsereturndata[count]}
Whathappensifthecopyconstructorthatiscalledforthereturnvalueinthelastlinethrowsanexceptionwhenthevalueisreturned?Thepoppedelementisnotreturnedbecauseoftheexception,andyetcounthasalreadybeendecremented,sothetopelementyouwantedislostforever!Theproblemisthatthisfunctionattemptstodotwothingsatonce:(1)returnavalue,and(2)changethestateofthestack.Itisbettertoseparatethesetwoactionsintotwoseparatememberfunctions,whichisexactlywhatthestandardstackclassdoes.(Inotherwords,followthedesignpracticeofcohesioneveryfunctionshoulddoonethingwell.)Exceptionsafecodeleavesobjectsinaconsistentstateanddoesnotleakresources.
Youalsoneedtobecarefulwritingcustomassignmentoperators.InChapter12ofVolume1,yousawthatoperator=shouldadheretothefollowingpattern:
1.Makesureyourenotassigningtoself.Ifyouare,gotostep6.(Thisisstrictlyanoptimization.)
2.Allocatenewmemoryrequiredbypointerdatamembers.
3.Copydatafromtheoldmemorytothenew.
4.Deletetheoldmemory.
5.Updatetheobjectsstatebyassigningthenewheappointerstothepointerdatamembers.
6.Return*this.
Itsimportanttonotchangethestateofyourobjectuntilallthenewpieceshavebeensafelyallocatedandinitialized.Agoodtechniqueistomovesteps2and3intoaseparatefunction,oftencalledclone().Thefollowingexampledoesthisforaclassthathastwopointermembers,theStringandtheInts:
//:C01:SafeAssign.cpp//AnExceptionsafeoperator=.#include#include//Forstd::bad_alloc#include#includeusingnamespacestd//AclassthathastwopointermembersusingtheheapclassHasPointers{//AHandleclasstoholdthedatastructMyData{constchar*theStringconstint*theIntssize_tnumIntsMyData(constchar*pString,constint*pInts,size_tnInts):theString(pString),theInts(pInts),numInts(nInts){}}*theData//Thehandle//Cloneandcleanupfunctions:staticMyData*clone(constchar*otherString,constint*otherInts,size_tnInts){
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 37/458
char*newChars=newchar[strlen(otherString)+1]int*newIntstry{newInts=newint[nInts]}catch(bad_alloc&){delete[]newCharsthrow}try{//Thisexampleusesbuiltintypes,soitwon't//throw,butforclasstypesitcouldthrow,sowe//useatryblockforillustration.(Thisisthe//pointoftheexample!)strcpy(newChars,otherString)for(size_ti=0itheString,otherData>theInts,otherData>numInts)}staticvoidcleanup(constMyData*theData){delete[]theData>theStringdelete[]theData>theIntsdeletetheData}public:HasPointers(constchar*someString,constint*someInts,size_tnumInts){theData=clone(someString,someInts,numInts)}HasPointers(constHasPointers&source){theData=clone(source.theData)}HasPointers&operator=(constHasPointers&rhs){if(this!=&rhs){MyData*newData=clone(rhs.theData>theString,rhs.theData>theInts,rhs.theData>numInts)cleanup(theData)theData=newData}return*this}~HasPointers(){cleanup(theData)}friendostream&operator
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 38/458
cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 39/458
theresourcesyourself.Basically,ifyoudontneedexceptions,yourenotforcedtousethem.
Newexceptions,oldcodeAnothersituationthatarisesisthemodificationofanexistingprogramthatdoesntuseexceptions.Youmightintroducealibrarythatdoesuseexceptionsandwonderifyouneedtomodifyallyourcodethroughouttheprogram.Assumingyouhaveanacceptableerrorhandlingschemealreadyinplace,themoststraightforwardthingtodoissurroundthelargestblockthatusesthenewlibrary(thismightbeallthecodeinmain())withatryblock,followedbyacatch(...)andbasicerrormessage).Youcanrefinethistowhateverdegreenecessarybyaddingmorespecifichandlers,but,inanycase,thecodeyoumustaddcanbeminimal.Itsevenbettertoisolateyourexceptiongeneratingcodeinatryblockandwritehandlerstoconverttheexceptionsintoyourexistingerrorhandlingscheme.
Itstrulyimportanttothinkaboutexceptionswhenyourecreatingalibraryforsomeoneelsetouse,especiallyifyoucantknowhowtheyneedtorespondtocriticalerrorconditions(recalltheearlierdiscussionsonexceptionsafetyandwhytherearenoexceptionspecificationsintheStandardC++Library).
TypicalusesofexceptionsDouseexceptionstodothefollowing:
Fixtheproblemandretrythefunctionthatcausedtheexception.
Patchthingsupandcontinuewithoutretryingthefunction.
Dowhateveryoucaninthecurrentcontextandrethrowthesameexceptiontoahighercontext.
Dowhateveryoucaninthecurrentcontextandthrowadifferentexceptiontoahighercontext.
Terminatetheprogram.
Wrapfunctions(especiallyClibraryfunctions)thatuseordinaryerrorschemessotheyproduceexceptionsinstead.
Simplify.Ifyourerrorhandlingschememakesthingsmorecomplicated,itispainfulandannoyingtouse.Exceptionscanbeusedtomakeerrorhandlingsimplerandmoreeffective.
Makeyourlibraryandprogramsafer.Thisisashortterminvestment(fordebugging)andalongterminvestment(forapplicationrobustness).
WhentouseexceptionspecificationsTheexceptionspecificationislikeafunctionprototype:ittellstheusertowriteexceptionhandlingcodeandwhatexceptionstohandle.Ittellsthecompilertheexceptionsthatmightcomeoutofthisfunctionsothatitcandetectviolationsatruntime.
Youcantalwayslookatthecodeandanticipatewhichexceptionswillarisefromaparticularfunction.Sometimes,thefunctionsitcallsproduceanunexpectedexception,andsometimesanoldfunctionthatdidntthrowanexceptionisreplacedwithanewonethatdoes,andyougetacalltounexpected().Anytimeyouuseexceptionspecificationsorcallfunctionsthatdo,considercreatingyourownunexpected()functionthatlogsamessageandtheneitherthrowsanexceptionorabortstheprogram.
Asweexplainedearlier,youshouldavoidusingexceptionspecificationsintemplateclasses,sinceyoucantanticipatewhattypesofexceptionsthetemplateparameterclassesmightthrow.
StartwithstandardexceptionsCheckouttheStandardC++libraryexceptionsbeforecreatingyourown.Ifastandardexceptiondoeswhatyouneed,chancesareitsaloteasierforyourusertounderstandandhandle.
Iftheexceptiontypeyouwantisntpartofthestandardlibrary,trytoinheritonefromanexistingstandardexception.Itsniceifyouruserscanalwayswritetheircodetoexpectthewhat()functiondefinedintheexception()classinterface.
NestyourownexceptionsIfyoucreateexceptionsforyourparticularclass,itsagoodideatonesttheexceptionclasseseitherinsideyourclassorinsideanamespacecontainingyourclass,toprovideaclearmessagetothereaderthatthisexceptionisonlyforyourclass.Inaddition,itpreventspollutionoftheglobalnamespace.
YoucannestyourexceptionsevenifyourederivingthemfromC++Standardexceptions.
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 40/458
UseexceptionhierarchiesUsingexceptionhierarchiesisavaluablewaytoclassifythetypesofcriticalerrorsthatmightbeencounteredwithyourclassorlibrary.Thisgiveshelpfulinformationtousers,assiststheminorganizingtheircode,andgivesthemtheoptionofignoringallthespecifictypesofexceptionsandjustcatchingthebaseclasstype.Also,anyexceptionsaddedlaterbyinheritingfromthesamebaseclasswillnotforceallexistingcodetoberewrittenthebaseclasshandlerwillcatchthenewexception.
TheStandardC++exceptionsareagoodexampleofanexceptionhierarchy.Buildyourexceptionsontopofitifyoucan.
Multipleinheritance(MI)AsyoullreadinChapter9,theonlyessentialplaceforMIisifyouneedtoupcastanobjectpointertotwodifferentbaseclassesthatis,ifyouneedpolymorphicbehaviorwithbothofthosebaseclasses.Itturnsoutthatexceptionhierarchiesareusefulplacesformultipleinheritancebecauseabaseclasshandlerfromanyoftherootsofthemultiplyinheritedexceptionclasscanhandletheexception.
Catchbyreference,notbyvalueAsyousawinthesectionExceptionmatching,youshouldcatchexceptionsbyreferencefortworeasons:
Toavoidmakinganeedlesscopyoftheexceptionobjectwhenitispassedtothehandler.
Toavoidobjectslicingwhencatchingaderivedexceptionasabaseclassobject.
Althoughyoucanalsothrowandcatchpointers,bydoingsoyouintroducemorecouplingthethrowerandthecatchermustagreeonhowtheexceptionobjectisallocatedandcleanedup.Thisisaproblembecausetheexceptionitselfmighthaveoccurredfromheapexhaustion.Ifyouthrowexceptionobjects,theexceptionhandlingsystemtakescareofallstorage.
ThrowexceptionsinconstructorsBecauseaconstructorhasnoreturnvalue,youvepreviouslyhadtwowaystoreportanerrorduringconstruction:
Setanonlocalflagandhopetheuserchecksit.
Returnanincompletelycreatedobjectandhopetheuserchecksit.
ThisproblemisseriousbecauseCprogrammersexpectthatobjectcreationisalwayssuccessful,whichisnotunreasonableinCbecausethetypesaresoprimitive.ButcontinuingexecutionafterconstructionfailsinaC++programisaguaranteeddisaster,soconstructorsareoneofthemostimportantplacestothrowexceptionsnowyouhaveasafe,effectivewaytohandleconstructorerrors.However,youmustalsopayattentiontopointersinsideobjectsandthewaycleanupoccurswhenanexceptionisthrowninsideaconstructor.
DontcauseexceptionsindestructorsBecausedestructorsarecalledintheprocessofthrowingotherexceptions,youllneverwanttothrowanexceptioninadestructororcauseanotherexceptiontobethrownbysomeactionyouperforminthedestructor.Ifthishappens,anewexceptioncanbethrownbeforethecatchclauseforanexistingexceptionisreached,whichwillcauseacalltoterminate().
Ifyoucallanyfunctionsinsideadestructorthatcanthrowexceptions,thosecallsshouldbewithinatryblockinthedestructor,andthedestructormusthandleallexceptionsitself.Nonemustescapefromthedestructor.
AvoidnakedpointersSeeWrapped.cppearlierinthischapter.Anakedpointerusuallymeansvulnerabilityintheconstructorifresourcesareallocatedforthatpointer.Apointerdoesnthaveadestructor,sothoseresourcesarentreleasedifanexceptionisthrownintheconstructor.Useauto_ptrorothersmartpointertypes forpointersthatreferenceheapmemory.
OverheadWhenanexceptionisthrown,theresconsiderableruntimeoverhead(butitsgoodoverhead,sinceobjectsarecleanedupautomatically!).Forthisreason,youneverwanttouseexceptionsaspartofyournormalflowofcontrol,nomatterhowtemptingandcleveritmayseem.Exceptionsshouldoccuronlyrarely,sotheoverheadispiledontheexceptionandnotonthenormallyexecutingcode.Oneoftheimportantdesigngoalsforexceptionhandlingwasthatitcouldbeimplementedwithnoimpactonexecutionspeedwhenitwasntusedthatis,aslongasyoudontthrowanexception,yourcoderunsasfastasitwouldwithout
[10]
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 41/458
exceptionhandling.Whetherthisistruedependsontheparticularcompilerimplementationyoureusing.(Seethedescriptionofthezerocostmodellaterinthissection.)
Youcanthinkofathrowexpressionasacalltoaspecialsystemfunctionthattakestheexceptionobjectasanargumentandbacktracksupthechainofexecution.Forthistowork,extrainformationneedstobeputonthestackbythecompiler,toaidinstackunwinding.Tounderstandthis,youneedtoknowabouttheruntimestack.
Wheneverafunctioniscalled,informationaboutthatfunctionispushedontotheruntimestackinanactivationrecordinstance(ARI),alsocalledastackframe.Atypicalstackframecontainstheaddressofthecallingfunction(soexecutioncanreturntoit),apointertotheARIofthefunctionsstaticparent(thescopethatlexicallycontainsthecalledfunction,sovariablesglobaltothefunctioncanbeaccessed),andapointertothefunctionthatcalledit(itsdynamicparent).Thepaththatlogicallyresultsfromrepetitivelyfollowingthedynamicparentlinksisthedynamicchain,orcallchain,thatwevementionedpreviouslyinthischapter.Thisishowexecutioncanbacktrackwhenanexceptionisthrown,anditisthemechanismthatmakesitpossibleforcomponentsdevelopedwithoutknowledgeofoneanothertocommunicateerrorsatruntime.
Toenablestackunwindingforexceptionhandling,extraexceptionrelatedinformationabouteachfunctionneedstobeavailableforeachstackframe.Thisinformationdescribeswhichdestructorsneedtobecalled(sothatlocalobjectscanbecleanedup),indicateswhetherthecurrentfunctionhasatryblock,andlistswhichexceptionstheassociatedcatchclausescanhandle.Thereisspacepenaltyforthisextrainformation,soprogramsthatsupportexceptionhandlingcanbesomewhatlargerthanthosethatdont. Eventhecompiletimesizeofprogramsusingexceptionhandlingisgreater,sincethelogicofhowtogeneratetheexpandedstackframesduringruntimemustbegeneratedbythecompiler.
Toillustratethis,wecompiledthefollowingprogrambothwithandwithoutexceptionhandlingsupportinBorlandC++BuilderandMicrosoftVisualC++:
//:C01:HasDestructor.cpp{O}classHasDestructor{public:~HasDestructor(){}}voidg()//Forallweknow,gmaythrow.voidf(){HasDestructorhg()}///:~
Ifexceptionhandlingisenabled,thecompilermustkeepinformationabout~HasDestructor()availableatruntimeintheARIforf()(soitcandestroyhproperlyshouldg()throwanexception).Thefollowingtablesummarizestheresultofthecompilationsintermsofthesizeofthecompiled(.obj)files(inbytes).
Compiler\Mode WithExceptionSupport
WithoutExceptionSupport
Borland 616 234
Microsoft 1162 680
Donttakethepercentagedifferencesbetweenthetwomodestooseriously.Rememberthatexceptions(should)typicallyconstituteasmallpartofaprogram,sothespaceoverheadtendstobemuchsmaller(usuallybetween5and15percent).
Thisextrahousekeepingslowsdownexecution,butaclevercompilerimplementationavoidsthis.Sinceinformationaboutexceptionhandlingcodeandtheoffsetsoflocalobjectscanbecomputedonceatcompiletime,suchinformationcanbekeptinasingleplaceassociatedwitheachfunction,butnotineachARI.YouessentiallyremoveexceptionoverheadfromeachARIandthusavoidtheextratimetopushthemontothestack.Thisapproachiscalledthezerocostmodel ofexceptionhandling,andtheoptimizedstoragementionedearlierisknownastheshadowstack.
Summary
[11]
[12]
[13]
[14]
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 42/458
Errorrecoveryisafundamentalconcernforeveryprogramyouwrite.ItsespeciallyimportantinC++whencreatingprogramcomponentsforotherstouse.Tocreatearobustsystem,eachcomponentmustberobust.
ThegoalsforexceptionhandlinginC++aretosimplifythecreationoflarge,reliableprogramsusinglesscodethancurrentlypossible,withmoreconfidencethatyourapplicationdoesnthaveanunhandlederror.Thisisaccomplishedwithlittleornoperformancepenaltyandwithlowimpactonexistingcode.
Basicexceptionsarenotterriblydifficulttolearnbeginusingtheminyourprogramsassoonasyoucan.Exceptionsareoneofthosefeaturesthatprovideimmediateandsignificantbenefitstoyourproject.
ExercisesSolutionstoselectedexercisescanbefoundintheelectronicdocumentTheThinkinginC++Volume2AnnotatedSolutionGuide,availableforasmallfeefromwww.MindView.net.
1.Writethreefunctions:onethatreturnsanerrorvaluetoindicateanerrorcondition,onethatsetserrno,andonethatusessignal().Writecodethatcallsthesefunctionsandrespondstotheerrors.Nowwriteafourthfunctionthatthrowsanexception.Callthisfunctionandcatchtheexception.Describethedifferencesbetweenthesefourapproaches,andwhyexceptionhandlingisanimprovement.
2.Createaclasswithmemberfunctionsthatthrowexceptions.Withinthisclass,makeanestedclasstouseasanexceptionobject.Ittakesasingleconstchar*asitsargumentthisrepresentsadescriptionstring.Createamemberfunctionthatthrowsthisexception.(Statethisinthefunctionsexceptionspecification.)Writeatryblockthatcallsthisfunctionandacatchclausethathandlestheexceptionbydisplayingitsdescriptionstring.
3.RewritetheStashclassfromChapter13ofVolume1sothatitthrowsout_of_rangeexceptionsforoperator[].
4.Writeagenericmain()thattakesallexceptionsandreportsthemaserrors.5.Createaclasswithitsownoperatornew.Thisoperatorshouldallocatetenobjects,andonthe
eleventhobjectrunoutofmemoryandthrowanexception.Alsoaddastaticmemberfunctionthatreclaimsthismemory.Nowcreateamain()withatryblockandacatchclausethatcallsthememoryrestorationroutine.Puttheseinsideawhileloop,todemonstraterecoveringfromanexceptionandcontinuingexecution.
6.Createadestructorthatthrowsanexception,andwritecodetoprovetoyourselfthatthisisabadideabyshowingthatifanewexceptionisthrownbeforethehandlerfortheexistingoneisreached,terminate()iscalled.
7.Provetoyourselfthatallexceptionobjects(theonesthatarethrown)areproperlydestroyed.8.Provetoyourselfthatifyoucreateanexceptionobjectontheheapandthrowthepointertothat
object,itwillnotbecleanedup.9.Writeafunctionwithanexceptionspecificationthatcanthrowfourexceptiontypes:achar,anint,
abool,andyourownexceptionclass.Catcheachinmain()andverifythecatch.Deriveyourexceptionclassfromastandardexception.Writethefunctioninsuchawaythatthesystemrecoversandtriestoexecuteitagain.
10.Modifyyoursolutiontothepreviousexercisetothrowadoublefromthefunction,violatingtheexceptionspecification.Catchtheviolationwithyourownunexpectedhandlerthatdisplaysamessageandexitstheprogramgracefully(meaningabort()isnotcalled).
11.WriteaGarageclassthathasaCarthatishavingtroubleswithitsMotor.UseafunctionleveltryblockintheGarageclassconstructortocatchanexception(thrownfromtheMotorclass)whenitsCarobjectisinitialized.ThrowadifferentexceptionfromthebodyoftheGarageconstructorshandlerandcatchitinmain().
2:DefensiveProgrammingWritingperfectsoftwaremaybeanelusivegoalfordevelopers,butafewdefensivetechniques,routinelyapplied,cangoalongwaytowardimprovingthequalityofyourcode.
Althoughthecomplexityoftypicalproductionsoftwareguaranteesthattesterswillalwayshaveajob,wehopeyoustillyearntoproducedefectfreesoftware.Objectorienteddesigntechniquesdomuchtocorralthedifficultyoflargeprojects,buteventuallyyoumustwriteloopsandfunctions.Thesedetailsof
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 43/458
programminginthesmallbecomethebuildingblocksofthelargercomponentsneededforyourdesigns.Ifyourloopsareoffbyoneoryourfunctionscalculatethecorrectvaluesonlymostofthetime,youreintroublenomatterhowfancyyouroverallmethodology.Inthischapter,youllseepracticesthathelpcreaterobustcoderegardlessofthesizeofyourproject.
Yourcodeis,amongotherthings,anexpressionofyourattempttosolveaproblem.Itshouldbecleartothereader(includingyourself)exactlywhatyouwerethinkingwhenyoudesignedthatloop.Atcertainpointsinyourprogram,youshouldbeabletomakeboldstatementsthatsomeconditionorotherholds.(Ifyoucant,youreallyhaventyetsolvedtheproblem.)Suchstatementsarecalledinvariants,sincetheyshouldinvariablybetrueatthepointwheretheyappearinthecodeifnot,eitheryourdesignisfaulty,oryourcodedoesnotaccuratelyreflectyourdesign.
ConsideraprogramthatplaystheguessinggameofHiLo.Onepersonthinksofanumberbetween1and100,andtheotherpersonguessesthenumber.(Wellletthecomputerdotheguessing.)Thepersonwhoholdsthenumbertellstheguesserwhethertheirguessishigh,loworcorrect.Thebeststrategyfortheguesserisabinarysearch,whichchoosesthemidpointoftherangeofnumberswherethesoughtafternumberresides.Thehighlowresponsetellstheguesserwhichhalfofthelistholdsthenumber,andtheprocessrepeats,halvingthesizeoftheactivesearchrangeoneachiteration.Sohowdoyouwritealooptodrivetherepetitionproperly?Itsnotsufficienttojustsay
boolguessed=falsewhile(!guessed){...}
becauseamalicioususermightresponddeceitfully,andyoucouldspendalldayguessing.Whatassumption,howeversimple,areyoumakingeachtimeyouguess?Inotherwords,whatconditionshouldholdbydesignoneachloopiteration?
Thesimpleassumptionisthatthesecretnumberiswithinthecurrentactiverangeofunguessednumbers:[1,100].Supposewelabeltheendpointsoftherangewiththevariableslowandhigh.Eachtimeyoupassthroughtheloopyouneedtomakesurethatifthenumberwasintherange[low,high]atthebeginningoftheloop,youcalculatethenewrangesothatitstillcontainsthenumberattheendofthecurrentloopiteration.
Thegoalistoexpresstheloopinvariantincodesothataviolationcanbedetectedatruntime.Unfortunately,sincethecomputerdoesntknowthesecretnumber,youcantexpressthisconditiondirectlyincode,butyoucanatleastmakeacommenttothateffect:
while(!guessed){//INVARIANT:thenumberisintherange[low,high]...}
Whathappenswhentheusersaysthataguessistoohighortoolowwhenitisnt?Thedeceptionwillexcludethesecretnumberfromthenewsubrange.Becauseoneliealwaysleadstoanother,eventuallyyourrangewilldiminishtonothing(sinceyoushrinkitbyhalfeachtimeandthesecretnumberisntinthere).Wecanexpressthisconditioninthefollowingprogram:
//:C02:HiLo.cpp{RunByHand}//PlaysthegameofHiLotoillustratealoopinvariant.#include#include#includeusingnamespacestdintmain(){cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 44/458
}intguess=(low+high)/2cout
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 45/458
cyclesneededtotestallassertionsatruntimemightbetoomuchofaperformancehitinthefield.Ifthatsthecase,youcanremovealltheassertioncodeautomaticallybydefiningthemacroNDEBUGandrebuildingtheapplication.
Toseehowthisworks,notethatatypicalimplementationofassert()lookssomethinglikethis:
#ifdefNDEBUG#defineassert(cond)((void)0)#elsevoidassertImpl(constchar*,constchar*,long)#defineassert(cond)\((cond)?(void)0:assertImpl(???))#endif
WhenthemacroNDEBUGisdefined,thecodedecaystotheexpression(void)0,soallthatsleftinthecompilationstreamisanessentiallyemptystatementasaresultofthesemicolonyouappendedtoeachassert()invocation.IfNDEBUGisnotdefined,assert(cond)expandstoaconditionalstatementthat,whencondiszero,callsacompilerdependentfunction(whichwenamedassertImpl())withastringargumentrepresentingthetextofcond,alongwiththefilenameandlinenumberwheretheassertionappeared.(Weused???asaplaceholderintheexample,butthestringmentionedisactuallycomputedthere,alongwiththefilenameandthelinenumberwherethemacrooccursinthatfile.Howthesevaluesareobtainedisimmaterialtoourdiscussion.)Ifyouwanttoturnassertionsonandoffatdifferentpointsinyourprogram,youmustnotonly#defineor#undefNDEBUG,butyoumustalsoreinclude.MacrosareevaluatedasthepreprocessorencountersthemandthususewhateverNDEBUGstateappliesatthepointofinclusion.ThemostcommonwaytodefineNDEBUGonceforanentireprogramisasacompileroption,whetherthroughprojectsettingsinyourvisualenvironmentorviathecommandline,asin:
myccDNDEBUGmyfile.cpp
MostcompilersusetheDflagtodefinemacronames.(Substitutethenameofyourcompilersexecutableformyccabove.)Theadvantageofthisapproachisthatyoucanleaveyourassertionsinthesourcecodeasaninvaluablebitofdocumentation,andyetthereisnoruntimepenalty.BecausethecodeinanassertiondisappearswhenNDEBUGisdefined,itisimportantthatyouneverdoworkinanassertion.Onlytestconditionsthatdonotchangethestateofyourprogram.
WhetherusingNDEBUGforreleasedcodeisagoodidearemainsasubjectofdebate.TonyHoare,oneofthemostinfluentialcomputerscientistsofalltime, hassuggestedthatturningoffruntimecheckssuchasassertionsissimilartoasailingenthusiastwhowearsalifejacketwhiletrainingonlandandthendiscardsitwhenhegoestosea. Ifanassertionfailsinproduction,youhaveaproblemmuchworsethandegradationinperformance,sochoosewisely.
Notallconditionsshouldbeenforcedbyassertions.Usererrorsandruntimeresourcefailuresshouldbesignaledbythrowingexceptions,asweexplainedindetailinChapter1.Itistemptingtouseassertionsformosterrorconditionswhileroughingoutcode,withtheintenttoreplacemanyofthemlaterwithrobustexceptionhandling.Likeanyothertemptation,usecaution,sinceyoumightforgettomakeallthenecessarychangeslater.Remember:assertionsareintendedtoverifydesigndecisionsthatwillonlyfailbecauseoffaultyprogrammerlogic.Theidealistosolveallassertionviolationsduringdevelopment.Dontuseassertionsforconditionsthatarenttotallyinyourcontrol(forexample,conditionsthatdependonuserinput).Inparticular,youwouldntwanttouseassertionstovalidatefunctionargumentsthrowalogic_errorinstead.
TheuseofassertionsasatooltoensureprogramcorrectnesswasformalizedbyBertrandMeyerinhisDesignbyContractmethodology. Everyfunctionhasanimplicitcontractwithclientsthat,givencertainpreconditions,guaranteescertainpostconditions.Inotherwords,thepreconditionsaretherequirementsforusingthefunction,suchassupplyingargumentswithincertainranges,andthepostconditionsaretheresultsdeliveredbythefunction,eitherbyreturnvalueorbysideeffect.
Whenclientprogramsfailtogiveyouvalidinput,youmusttellthemtheyhavebrokenthecontract.Thisisnotthebesttimetoaborttheprogram(althoughyourejustifiedindoingsosincethecontractwasviolated),butanexceptioniscertainlyappropriate.ThisiswhytheStandardC++librarythrowsexceptionsderivedfromlogic_error,suchasout_of_range. Iftherearefunctionsthatonlyyoucall,however,suchasprivatefunctionsinaclassofyourowndesign,theassert()macroisappropriate,sinceyouhavetotalcontroloverthesituationandyoucertainlywanttodebugyourcodebeforeshipping.
Apostconditionfailureindicatesaprogramerror,anditisappropriatetouseassertionsforanyinvariant
[15]
[16]
[17]
[18]
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 46/458
atanytime,includingthepostconditiontestattheendofafunction.Thisappliesinparticulartoclassmemberfunctionsthatmaintainthestateofanobject.IntheMyVectorexampleearlier,forinstance,areasonableinvariantforallpublicmemberfunctionswouldbe:
assert(0
-
5/3/2015 ThinkinginC++2ndedVolume2
file:///C:/Users/BERARDO/Downloads/TICPP2ndedVoltwo/html/TicV2.html#_Toc305593301 47/458
morerobust.
Whenyourcodepassesallyourtests,youknowthatifthesystemisntworking,yourcodeisprobablynottheproblem.ThestatementAllmytestspassisapowerfulargument.
AutomatedtestingSowhatdoesaunittestlooklike?Toooftendevelopersjustusesomewellbehavedinputtoproducesomeexpectedoutput,whichtheyinspectvisually.Twodangersexistinthisapproach.First,programsdontalwaysreceiveonlywellbehavedinput.Weallknowthatweshouldtesttheboundariesofprograminput,butitshardtothinkaboutthiswhenyouretryingtojustgetthingsworking.Ifyouwritethetestforafunctionfirstbeforeyoustartcoding,youcanwearyourtesterhatandaskyourself,Whatcouldpossiblymakethisbreak?Codeatestthatwillprovethefunctionyoullwriteisntbroken,andthenputonyourdeveloperhatandmakeithappen.Youllwritebettercodethanifyouhadntwrittenthetestfirst.
Theseconddangeristhatinspectingoutputvisuallyistediousanderrorprone.Mostanysuchthingahumancandoacomputercando,butwithouthumanerror.ItsbettertoformulatetestsascollectionsofBooleanexpressionsandhaveatestprogramreportanyfailures.
Forexample,supposeyouneedtobuildaDateclassthathasthefollowingproperties:
Adatecanbeinitializedwithastring(YYYYMMDD),threeintegers(Y,M,D),ornothing(givingtodaysdate).
Adateobjectcanyielditsyear,month,anddayorastringoftheformYYYYMMDD.
Allrelationalcomparisonsareavailable,aswellascomputingthedurati