458
 5/3/2015 Thi nki ng i n C++ 2nd ed Vol ume 2 fil e:///C :/U ser s/BERARDO /Do wnlo ads/TICPP- 2nd- ed- Vol -two/html /Tic V2.htm l# Toc305593301 1/458 Thinking In C++ Volume 2: Practical Programming Bruce Eckel, President, MindView, Inc. Chuck Allison, Utah Valley State College Book Home Page Annotated Solution Guide Report Errors Here Cover Introduction Part 1: Building Stable Systems 1: Exception handling 2: Defensive programming Part 2: The Standard C++ Library 3: Strings in depth 4: Iostreams 5: Templates in depth 6: Generic algorithms 7: Generic containers Part 3: Special Topics 8: Runtime type identification 9: Multiple inheritance 10: Design patterns 11: Concurrency Appendix A: Recommended readi ng B: Etc Index  I’d like to congratulate the both of you for a very impressive work! Not only did I find your book to be an enjoyable and rewarding read … I was astounded by the accuracy both in terms of technical correctness and use of the language … I believe that you have attained a level of craftsmanship that is simply outstanding.” Bjorn Karlsson Editorial Board, C/C++ Users Journal  “This book is a tremendous achievement . You owe it to yourself to have a copy on your she lf.” Al Stevens Contributing Editor, Doctor Dobbs Journal  “Eckel’s book is the only one to so clearly explain ho w to rethink program const ruction for ob ject orientation. That the book is also an excellent tutorial on the ins and outs of C++ is an added bonus.” Andrew Binstock Editor, Unix Review  “Bruce continues to amaz e me with his insight into C++, and Thinking in C++ is his best collection of ideas yet. If you want clear answers to difficult questions about C++, buy this outstanding book.” Gary Entsminger

Thinking in C++ 2nd ed Volume 2

Embed Size (px)

DESCRIPTION

Thinking in C++, Bruce Eckel

Citation preview

  • 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