10
Lab 9: C++ classes classes and objects, constructors and destructors, refactoring Goals After this lab you will be able to 1. Use classes in place of structs. 2. Write constructors and destructors for classes. 3. Use twodimensional arrays. 4. Refactor code. Apart from teaching you to use classes and 2darrays, this lab is designed to have you work repeatedly on the same code. By now you should be reading and writing code much more quickly than at the beginning of the class. You should also using your text editor more expertly, for example using searchandreplace, moving around quickly in the file, cutting and pasting lines using keystrokes, etc. You will spend many hours in your text editor during your degree and beyond: you should master it. Refactoring code (Task 3) is an activity that exercises your editor kungfu, and will not take too long if you use the editor well. Setup Note that these instructions no longer include all steps. You should know how to do these things by now. If in doubt, refer to previous lab instructions. In the terminal: 1. Add the new directory '9' to the root directory of your repository. This will be the working directory for all the instructions below. 2. Fetch the new material for Lab 9, stored in a compressed tarball : $ wget http://www.cs.sfu.ca/~vaughan/lab9.tgz 3. Expand the archive into the working directory: $ tar xzvf lab9.tgz Introducing C++ C++ extends the C language with support for classes to support ObjectOriented Programming , and templates to support Generic Programming . This week we will look at classes, but first a summary of the workflow changes you need to use C++. 1. C++ source code files have the conventional suffix ".cpp" or ".cc", instead of C's ".c". 2. C++ header files may have the suffix ".hpp" or ".hh", or stick with C's ".h". We will use ".hpp" to make it clear when we have a C++ header. 3. The GNU C++ compiler program is called "g++", instead of "gcc". Note that the intructions below do not provide compile commands for you to cut'n'paste. You will need to read the notes above and construct your own compile commands. A C++ primer for C programmers Here is a very good and concise introduction to C++ for C programmers. by Prof. Tom Anderson of the University of Washington . Prof. Anderson has strong opinions about the useful and lessuseful parts of C++, and draws your attention to the most important parts in less than 12 pages. The document is dated in some ways, but most of the advice is excellent. Things to do: 1. Read Sections 1 through 3 carefully: they will help with your Tasks this week.

Cmpt127 Lab 9

Embed Size (px)

DESCRIPTION

hi

Citation preview

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 1/10

    Lab9:C++classesclassesandobjects,constructorsanddestructors,refactoring

    Goals

    Afterthislabyouwillbeableto

    1. Useclassesinplaceofstructs.2. Writeconstructorsanddestructorsforclasses.3. Usetwodimensionalarrays.4. Refactorcode.

    Apartfromteachingyoutouseclassesand2darrays,thislabisdesignedtohaveyouworkrepeatedlyonthesamecode.Bynowyoushouldbereadingandwritingcodemuchmorequicklythanatthebeginningoftheclass.Youshouldalsousingyourtexteditormoreexpertly,forexampleusingsearchandreplace,movingaroundquicklyinthefile,cuttingandpastinglinesusingkeystrokes,etc.Youwillspendmanyhoursinyourtexteditorduringyourdegreeandbeyond:youshouldmasterit.

    Refactoringcode(Task3)isanactivitythatexercisesyoureditorkungfu,andwillnottaketoolongifyouusetheeditorwell.

    Setup

    Notethattheseinstructionsnolongerincludeallsteps.Youshouldknowhowtodothesethingsbynow.Ifindoubt,refertopreviouslabinstructions.

    Intheterminal:

    1. Addthenewdirectory'9'totherootdirectoryofyourrepository.Thiswillbetheworkingdirectoryforalltheinstructionsbelow.

    2. FetchthenewmaterialforLab9,storedinacompressedtarball:

    $wgethttp://www.cs.sfu.ca/~vaughan/lab9.tgz

    3. Expandthearchiveintotheworkingdirectory:

    $tarxzvflab9.tgz

    IntroducingC++C++extendstheClanguagewithsupportforclassestosupportObjectOrientedProgramming,andtemplatestosupportGenericProgramming.Thisweekwewilllookatclasses,butfirstasummaryoftheworkflowchangesyouneedtouseC++.

    1. C++sourcecodefileshavetheconventionalsuffix".cpp"or".cc",insteadofC's".c".2. C++headerfilesmayhavethesuffix".hpp"or".hh",orstickwithC's".h".Wewilluse

    ".hpp"tomakeitclearwhenwehaveaC++header.3. TheGNUC++compilerprogramiscalled"g++",insteadof"gcc".

    Notethattheintructionsbelowdonotprovidecompilecommandsforyoutocut'n'paste.Youwillneedtoreadthenotesaboveandconstructyourowncompilecommands.

    AC++primerforCprogrammers

    HereisaverygoodandconciseintroductiontoC++forCprogrammers.byProf.TomAndersonoftheUniversityofWashington.

    Prof.AndersonhasstrongopinionsabouttheusefulandlessusefulpartsofC++,anddrawsyourattentiontothemostimportantpartsinlessthan12pages.Thedocumentisdatedinsomeways,butmostoftheadviceisexcellent.

    Thingstodo:

    1. ReadSections1through3carefully:theywillhelpwithyourTasksthisweek.

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 2/10

    2. ReadSections4and5atyourleisure,andrememberthatopinionsvarywildlyonthissubject,andthingschangeovertime.

    3. NotethattheStandardTemplateLibrary(STL)isnowmatureandsupportedbymostcompilers,andyoucanandshoulduseitwithconfidence.WewillshowyouthebasicsoftheSTLinalaterlab.

    Notethatyoureallyareexpectedtoreadthedocument,andthefollowinginstructionsmaynotbeenoughbythemselvestohelpyousolvethetasks.Anothergoalofthislab(andtheclass)istoencourageyoutoreadaroundyoursubjectsandfeelpersonalresponsibilityforlearning.

    **STOP**READTHEPRIMERDOCUMENTBEFORECONTINUING**

    Task1:ImageclassWewilldevelopaC++program,usingideasfamiliarfrompreviouslabsplusnewsyntaxforcreatingclasses.

    Requirements

    1. ReadtheGuidesectiononclasses,constructorsanddestructorsbelow.2. WriteanewC++sourcefile"image.cpp"thatcontainsacompleteimplementationofthe

    ImageclassdeclaredintheprovidedC++headerfile"image.hpp".3. Yourfilemustinclude"image.hpp"withoutanymodifications.4. Writeyourownmain()functionfortestingyourclass,butputitinanothersourcefile:do

    notdefinemain()in"image.cpp"asthiswillinterferewiththeservertest.

    Submission

    Addandcommitthesinglefile"image.cpp"toyourrepo.

    Guide

    CtoC++

    HereisaninterfacedefinitionforanimagedatatypeinC,extendedfromtheonewedevelopedinanearlierlab:

    typedefstructimage{unsignedintcols;unsignedintrows;uint8_t*pixels;}img_t;

    /*Returnsanimg_tstructurecontaining0x0pixels.*/img_timg_create(void);

    /*Freesallmemoryallocatedforimg*/voidimg_destroy(img_t*img);

    /*Changesthesizeofanimage,allocatingmemoryasnecessary,andsettingallpixelstofillcolor.Returns0onsuccess,oranonzeroerrorcode.*/intimg_resize(img_t*img,unsignedintwidth,unsignedintheight,uint8_tfillcolor);

    /*Setsthecolorofthepixelat(x,y)tocolor.Returns0onsuccess,elseanonzeroerrorcode.If(x,y)isnotavalidpixel,thecallfailsandtheimagedoesnotchange.*/intimg_set_pixel(img_t*img,unsignedintx,unsignedinty,uint8_tcolor);

    /*Getsthecolorofthepixelat(x,y)andstoresattheaddresspointedtobypcolor.Returns0onsuccess,elseanonzeroerrorcode.*/intimg_get_pixel(img_t*img,unsignedintx,unsignedinty,uint8_t*pcolor);

    WecouldusethesedefinitionsasisinaC++program,sinceCisalmostasubsetofC++.However,animplementationinC++stylewouldhavethefollowingdifferences:

    1. Thestructurewouldbeaclass

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 3/10

    2. Thefunctionsoperatingonimagestructureswouldbemethodsoftheimageclass,andwouldnotneedthe"img_"prefix.

    3. Imageclassmethodsdononeedapointertotheimagedatastructure,sincetheyautomaticallyhaveathispointertotheobjectonwhichthemethodwascalled.

    4. Thefieldsofthestructwouldnotbeaccessiblefromoutsidetheclass:animagecouldonlybemodfifiedusingitsmethods.

    5. img_create()wouldbeaconstructor6. img_destroy()wouldbeadestructor

    HereistheC++version:

    classImage{

    private:unsignedintcols;unsignedintrows;uint8_t*pixels;

    public:/*Constructsanimageof0x0pixels.*/Image();

    /*Freesallmemoryallocatedforimg*/~Image();

    /*Changesthesizeofanimage,allocatingmemoryasnecessary,andsettingallpixelstofillcolor.Returns0onsuccess,oranonzeroerrorcode.*/intresize(unsignedintwidth,unsignedintheight,uint8_tfillcolor);

    /*Setsthecolorofthepixelat(x,y)tocolor.Returns0onsuccess,elseanonzeroerrorcode.If(x,y)isnotavalidpixel,thecallfailsandtheimagedoesnotchange.*/intset_pixel(unsignedintx,unsignedinty,uint8_tcolor);

    /*Getsthecolorofthepixelat(x,y)andstoresattheaddresspointedtobycolorp.Returns0onsuccess,elseanonzeroerrorcode.*/intget_pixel(unsignedintx,unsignedinty,uint8_t*colorp);};

    Heretheyareagainwithoutthecommentssothefunctionalpartsareeasiertocompare:

    C:

    typedefstructimage{unsignedintcols;unsignedintrows;uint8_t*pixels;}img_t;

    img_timg_create(void);voidimg_destroy(img_t*img);intimg_resize(img_t*img,unsignedintwidth,unsignedintheight,uint8_tfillcolor);intimg_set_pixel(img_t*img,unsignedintx,unsignedinty,uint8_tcolor);intimg_get_pixel(img_t*img,unsignedintx,unsignedinty,uint8_t*colorp);

    C++:

    classImage{private:unsignedintcols;unsignedintrows;uint8_t*pixels;

    public:Image();~Image();intresize(unsignedintwidth,unsignedintheight,uint8_tfillcolor);intset_pixel(unsignedintx,unsignedinty,uint8_tcolor);

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 4/10

    intget_pixel(unsignedintx,unsignedinty,uint8_t*colorp);};

    Examplesofusage,firstinC:

    img_timg=img_create();

    if(img_resize(&img,640,480,0)!=0){exit(1);//quit}for(inti=0;i

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 5/10

    Image::Image():cols(0),//initializationlistrows(0),pixels(NULL){//Noworktodoinconstructorbodyinthisexample://theintializationlisttookcareofit.//Allmembersnowhavesafeinitialvalues.}

    AweakpointoftheC++designisthathandlingerrorsinconstructorsisquitecomplicated,sincetheyhavenoreturnvalue.Itisagoodideatoavoiddoinganythinginaconstructorthatcouldfail,forexampleanysystemcallormemoryallocation.Thisiswhyinourexampleweconstructonly0x0pixelimages,anddoourpixelallocationinImage::resize()Ifanynewfails,yourprogramwillbeterminatedimmediately.Youcanchangethisbehaviourusingexceptionsbutthatisbeyondthescopeofthisclass.(SomepeoplethinkexceptionsareaBadIdea,forexampleGoogledoesnotallowtheminanyC++code).

    Destructors

    Wheneveranobjectisdestroyed,eitherbygoingoutofscopeorwhendeleteiscalledonitsaddress,thedestructorisautomaticallycalled.Youputmemorydeallocationandcleanupcodeinthedestructorsoyoucannotforgettorecycleresourceswhenyouarefinishedwithanobject.Afterthedestructorfinishes,thedestructorsofanydatamembersarecalled.

    Destructorshavethesamenameastheirclass,prefixedwitha'~'andtheyhavenoreturntypeorvalue.

    //containstheclassdeclarationforImage#include"image.hpp"

    Image::~Image(){//freeeverythingthatcouldhavebeenallocatedinsidethisobjectif(pixels!=NULL){delete[]pixels;}}

    Creatinganddestroyingobjects

    Objectscanbecreatedonthestack,justbydeclaringthem,andtheirmethodscalledusingdotsyntax:

    Imageimg;img.resize(100,100,255);//whitesquareimage

    Whenastackallocatedobjectgoesoutofscope,itsdestructoriscalledautomatically.

    Objectscanalsobeallocatedontheheapusingthenewkeywordfollowedbytheclassname.newreplacesmalloc()formostpurposesinC++.newreturnsapointertoaninstanceoftheclass,somembersandmethodsareaccessedusingarrowsyntax.

    Unfortunately,keepingtrackofpointerstodestructobjectsautomaticallyisquitecostly,soheapallocatedobjectsmustbedestroyedmanually:

    Image*img=newImage;img>resize(100,100,255);//whitesquareimage//(useimage,thenwhendone)deleteimg;

    OtherlanguagessuchasJavaandC#cankeeptrackofheapallocationsandsaveyouthetroubleofdeletingthings.Thisgarbagecollectionprocesscanbeverygoodforcoderobustness,butslowsthingsdownabit.

    InC++thebasicmemorysanitationstrategyis(i)writethoroughdestructorsand(ii)usestack

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 6/10

    variableswheneverpossible.Rememberyourstackissmallsobigthingsgoontheheap.Agoodapproachistohaveasmallstackallocatedwrapper/headerobjectforeachofyourheapallocatedbigthings,sothatwhenthewrapperobjectgoesoutofscopeitsdestructorcleansupproperly.TheImageclassfollowsthispattern.

    Defaultconstructors

    Aconstructorthattakesnoargumentsiscalledadefaultconstructor.Ifyoudonotspecifyanyconstructorforyourclass,adefaultconstructorisgeneratedautomaticallythatsimplycallstheconstructorsofalldatamembersoftheclass.Thebuiltintypes(int,float,etc)havedefaultconstructorsthatallocatespaceonly:theirvaluesareleftinitialized,likeinC.

    Creatingarraysofobjects

    Newanddeletehaveconvenientarrayforms,whichcanbeusedwithbuiltintypesandanyobjectthathasadefaultconstructor.

    int*arr=newint[100];//(useintarray,thenwhendone)delete[]arr;

    Forobjects,thedefaultconstructoriscalledforeveryiteminthearray.Similarlydelete[]callsthedestructoroneachiteminthearraybeforefreeingtheentirearray.

    Bubble*bubbles=newBubble[100];//produces100bubbles,allthesame//(usebubblearray,thenwhendone)delete[]bubbles;

    Teachthecontroversy

    Noteveryoneisafanofnewanddelete,andthis"rant"byStanfordprofessorDavidMaziresdiscussessomeoftheissuesthatbotherpeople.Followingtheauthor'sargumentwilltestandboostyourunderstandingofhowtheywork.

    Methods

    Classmethodsarelikenormalfunctions,buttheycanonlybecalledthroughanobjectoftherighttype.Akeyadvantageofthisisthatyoucannotpassinthewrongkindofpointer,oranullpointer.

    Methodsaredefinedbyprefixingthemethodnamewiththenameoftheclass:

    #include"image.hpp"

    intImage::resize(unsignedintwidth,unsignedintheight,uint8_tfillcolor){//dotheworkhere//...return0;}

    intImage::set_pixel(unsignedintx,unsignedinty,uint8_tcolor){//dotheworkhere//...return0;}

    //(etc)

    Insideaclass'smethods,allthemembersoftheclassareavailableusingjusttheirnames:

    intImage::set_pixel(unsignedintx,unsignedinty,uint8_tcolor){//x,y,andcolorarelocalvariables//pixelsandcolsaremembersofthisobjectpixels[y*cols+x]=color;

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 7/10

    return0;}

    Incaseamethodneedstoknowwhichobjectitwascalledon,apointercalledthisalwaysexists.thispointstotheobjectonwhichthemethodwascalled.Sothiscodeisidenticaltotheabove:

    intImage::set_pixel(unsignedintx,unsignedinty,uint8_tcolor){//x,y,andcolorarelocalvariables//pixelsandcolsaremembersofthisobject//socanbeaccessedthroughthe'this'pointerthis>pixels[y*this>cols+x]=color;return0;}

    Insideanobject'smethods,itsothermethodsarealsoavailableusingtheirnamealone,orthroughthethispointer:

    voidImage::set_grey_all_over(void){for(inty=0;yrowsfor(intx=0;xcolsset_pixel(x,y,128);//this>set_pixel()}

    Onceanobjectisconstructed,itsdatamembersandmethodsareaccessedusingdotorarrowsyntax,justlikestructures,exceptthatnowwecanaccessanobject'smethodstooperateonit:

    Imagei();i.resize(640,480,0);i.set_pixel(100,100,255);

    Image*j=newImage();j>resize(640,480,0);j>set_pixel(100,100,255);

    Task2:Save&LoadExtendyourImageclassbyaddingsave()andload()methods.Thefileformatisuptoyou.Itcanbetextorbinary,aslongastheload()loadsthesave()'dformatcorrectly.

    Requirements

    1. WriteanewC++sourcefile"image2.cpp"thatcontainsacompleteimplementationoftheImageclassdeclaredintheprovidedC++headerfile"image2.hpp".

    2. Yourfilemustinclude"image2.hpp"withoutanymodifications.3. Writeyourownmain()functionfortestingyourclass,butputitinanothersourcefile:do

    notdefinemain()in"image2.cpp"asthiswillinterferewiththeservertest.

    Submission

    Addandcommitthesinglefile"image2.cpp"toyourrepo.

    Guide

    SeeLab6forfileI/Otutorialandexamples.

    Task3:Alternateimplementationusing2DarraysChangetheinternalrepresentationoftheimageinyourImageclass,withoutchangingtheexternalinterface.

    Wewilluseamultidimensionalarraytostorepixelsinsteadoftheonedimensionalpixelarraywehaveusedsofar.

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 8/10

    Theprocessofrevisingyourimplementationwithoutchangingtheinterfaceorexternalbehaviouriscalledrefactoringandcanbeveryimportantforkeepingcodemaintainable,particularlyafteraperiodofaddingalotoffeaturesorbugfixes.Tidyingupamessyimplementationbeforeitgetstoocomplicatedformortalstounderstandisusefulwork.Ontheotherhandyoushouldresisttinkeringforthesakeofit:youriskintroducingbugs.

    Requirements

    Thesuppliedfile"image3.hpp"differsfrom"image2.hpp"onlyinthatitdeclarestheprivatepixeldatapointertobeoftypeuint8_t**.YoumustreimplementtheImageclassusinga2Darray.Thiswillmakememoryallocationcodealittlemorecomplex(seetheGuidebelow),butmakeaccessingpixelseasierandarguablymakethecodemorereadable.Certainimageoperationsyouimplementedinanearlierlabcouldbefasteroreasierusing2Darrays:youdonothavetoimplementthemhere,butyoushouldthinkaboutwhichoneswouldbenefit.

    1. WriteanewC++sourcefile"image3.cpp"thatcontainsacompleteimplementationoftheImageclassdeclaredintheprovidedC++headerfile"image3.hpp".

    2. Yourfilemustinclude"image3.hpp"withoutanymodifications.3. Notethatsincetheinterfaceoftheclass(i.e.thepublicmethods)didnotchange,youcan

    usethesamemain()programtotestitasfortheprevioustasks.Makesurenomain()functionexistsin"image3.cpp".

    Caution

    save()andload()needsomecarefulthought.Favourcorrectnessoverspeed,buttrynottomaketoomanysystemcalls:theyareslow.

    Submission

    Addandcommitthesinglefile"image3.cpp"toyourrepo.

    Guide

    CandC++supportmultidimensionalarrays.Thesyntaxisverysimplebuttheunderlyingmodelisalittlecomplex.Considerthesearrays,wherea2Darrayisdeclaredandusedinthewayyoumightguessbyextrapolatingfromthe1Dcase:

    intA[16];//1Darrayof16elementsintB[4][4];//2Darrayof4x4elements

    //setseveryelementinAfor(inta=0;a

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 9/10

    'A'isoftypearrayofint.'B'isoftypearrayofarrayofint.Youcanseethatthereissomeoverheadinusingthe2Darray,aswerequiremorememoryspaceandatwosteplookuptofindtheintegerofinterest.

    Moredimensions

    Thearraydeclarationandaccesssyntaxworksforarbitrarynumbersofdimensions:

    intC[3][3][3];//3Darrayof9intsintD[20][5][10][4];//4Darrayof20*5*10*4ints

    C[0][0][0]=99;D[101][2][1][0]=99;

    Inpractice,arraysofmorethan3dimensionsarerarelyused.

    Building2Darraysontheheap

    Theexamplesaboveshowmultidimensionalarraysallocatedonthestack.Theycanalsobeallocatedmanuallyontheheap.ThisexamplebuildsarraysAandBontheheap(omittingerrorchecking)inC:

    int*A=malloc(16*sizeof(int));

    int**B=malloc(4*sizeof(int*));

  • 14/05/2015 CMPT127Lab9

    http://www.cs.sfu.ca/CourseCentral/127/vaughan/lab/9/ 10/10

    for(inti=0;i