Tải bản đầy đủ - 0 (trang)
Chapter 14. REUSING CODE IN C++

Chapter 14. REUSING CODE IN C++

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

Chapter10,"ObjectsandClasses,"introducedfunction

templates.Nowwe'lllookatclasstemplates,whichprovide

anotherwayofreusingcode.Classtemplatesletyoudefinea

classingenericterms.Thenyoucanusethetemplatetocreate

specificclassesdefinedforspecifictypes.Forexample,you

coulddefineageneralstacktemplateandthenusethe

templatetocreateoneclassrepresentingastackofintvalues

andanotherclassrepresentingastackofdoublevalues.You

couldevengenerateaclassrepresentingastackofstacks.



ClasseswithObjectMembers

Let'sbeginwithclassesthatincludeclassobjectsasmembers.

Someclasses,suchastheStringclassofChapter12,"Classes

andDynamicMemoryAllocation,"orthestandardC++classes

andtemplatesofChapter16,"ThestringClassandthe

StandardTemplateLibrary,"offerconvenientwaysof

representingcomponentsofamoreextensiveclass.We'lllook

ataparticularexamplenow.

Whatisastudent?Someoneenrolledinaschool?Someone

engagedinthoughtfulinvestigation?Arefugeefromtheharsh

exigenciesoftherealworld?Someonewithanidentifyingname

andasetofquizscores?Clearly,thelastdefinitionisatotally

inadequatecharacterizationofaperson,butitiswell-suitedfor

asimplecomputerrepresentation.Solet'sdevelopaStudent

classbasedonthatdefinition.

Simplifyingastudenttoanameandasetofquizscores

suggestsusingaStringclassobject(Chapter12)toholdthe

nameandanarrayclassobject(comingupsoon)toholdthe

scores(assumedtobetypedouble).(Onceyoulearnaboutthe

libraryclassesdiscussedinChapter16,youprobablywoulduse

thestandardstringandvectorclasses.)Youmightbe

temptedtopubliclyderiveaStudentclassfromthesetwo

classes.Thatwouldbeanexampleofmultiplepublic

inheritance,whichC++allows,butitwouldbeinappropriate

here.Thereasonisthattherelationshipofastudenttothese

classesdoesn'tfittheis-amodel.Astudentisnotaname.A

studentisnotanarrayofquizscores.Whatwehavehereisa

has-arelationship.Astudenthasaname,andastudenthasan

arrayofquizscores.TheusualC++techniqueformodeling

has-arelationshipsistousecompositionorcontainment;that

is,tocreateaclasscomposedof,orcontaining,membersthat

areobjectsofanotherclass.Forexample,wecanbegina



Studentclassdeclarationlikethis:

classStudent

{

private:

Stringname;//useaStringobjectforname

ArrayDbscores;//useanArrayDbobjectforscores

......

};

Asusual,theclassmakesthedatamembersprivate.This

impliesthattheStudentclassmemberfunctionscanusethe

publicinterfacesoftheStringandArrayDb(forarrayof

double)classestoaccessandmodifythenameandscores

objects,butthattheoutsideworldcannotdoso.Theonly

accesstheoutsideworldwillhavetonameandscoresis

throughthepublicinterfacedefinedfortheStudentclass(see

Figure14.1).Acommonwayofdescribingthisissayingthat

theStudentclassacquirestheimplementationofitsmember

objects,butdoesn'tinherittheinterface.Forexamplea

StudentobjectusestheStringimplementationratherthana

char*nameoracharname[26]implementationforholding

thename.ButaStudentobjectdoesnotinnatelyhavethe

abilitytousetheStringoperator==()function.



Figure14.1.Containment.



InterfacesandImplementations

Withpublicinheritance,aclassinheritsaninterface,and,perhaps,an

implementation.(Purevirtualfunctionsinabaseclasscanprovidean

interfacewithoutanimplementation.)Acquiringtheinterfaceispartof

theis-arelationship.Withcomposition,ontheotherhand,aclass

acquirestheimplementationwithouttheinterface.Notinheritingthe

interfaceispartofthehas-arelationship.



Thefactthataclassobjectdoesn'tautomaticallyacquirethe

interfaceofacontainedobjectisagoodthingforahas-a

relationship.Forexample,onecouldextendtheStringclassto

overloadthe+operatortoallowconcatenatingtwostrings,but,

conceptually,itdoesn'tmakesensetoconcatenatetwoStudent

objects.That'sonereasonnottousepublicinheritanceinthis

case.Ontheotherhand,partsoftheinterfaceforthecontained

classmaymakesenseforthenewclass.Forexample,you



mightwanttousetheoperator<()methodfromtheString

interfacetosortStudentobjectsbyname.Youcandosoby

definingaStudent::Operator<()memberfunctionthat,

internally,usestheString::Operator<()function.Let'smove

ontosomedetails.



TheArrayDbClass

ThefirstdetailisdevelopingtheArrayDbclasssothatthe

Studentclasscanuseit.Thisclasswillbequitesimilartothe

Stringclassbecausethelatterisanarray,too,inthiscase,of

char.First,let'slistsomenecessaryand/ordesirablefeatures

fortheArrayDbclass.

Itshouldbeabletostoreseveraldoublevalues.

Itshouldproviderandomaccesstoindividualvaluesusing

bracketnotationwithanindex.

Onecanassignonearraytoanother.

Theclasswillperformboundscheckingtoensurethatarray

indicesarevalid.

Thefirsttwofeaturesaretheessenceofanarray.Thethird

featureisnottrueofbuilt-inarraysbutistrueforclassobjects,

socreatinganarrayclasswillprovidethatfeature.Thefinal

feature,again,isnottrueforbuilt-inarrays,butcanbeadded

aspartofthesecondfeature.

Atthispoint,muchofthedesigncanapetheString

declaration,replacingtypecharwithtypedouble.Thatis,you

candothis:



classArrayDb

{

private:



unsignedintsize;//numberofarrayelem



double*arr;//addressoffirstele

public:

ArrayDb();//defaultconstructor

//createanArrayDbofnelements,seteachtoval

ArrayDb(unsignedintn,doubleval=0.0);

//createanArrayDbofnelements,initializetoarraypn

ArrayDb(constdouble*pn,unsignedintn);

ArrayDb(constArrayDb&a);//copyconstructor

virtual~ArrayDb();//destructor

double&operator[](inti);//arrayindexing

constdouble&operator[](inti)const;//arrayindexing

//otherstufftobeaddedhere

ArrayDb&operator=(constArrayDb&a);



friendostream&operator<<(ostream&os,constArrayDb&a



};

Theclasswillusedynamicmemoryallocationtocreateanarray

ofthedesiredsize.Therefore,italsowillprovideadestructor,a

copyconstructor,andanassignmentoperator.Forconvenience,

itwillhaveafewmoreconstructors.



Tweakingoperator[]()

Toproviderandomaccessusingarraynotation,theclasshasto

overloadthe[]operator,justastheStringclassdid.Thiswill

allowcodelikethefollowing:

ArrayDbscores(5,20.0);//5elements,eachsetto20.0

doubletemp=scores[3];

scores[3]=16.5:

ClientsoftheArrayDBclasscanaccessarrayelements

individuallyonlythroughtheoverloaded[]operator.Thisgives

youtheopportunitytobuildinsomesafetychecks.In

particular,themethodcanchecktoseeiftheproposedarray

indexisinbounds.Thatis,youcanwritetheoperatorthisway:

double&ArrayDb::operator[](inti)

{

//checkindexbeforecontinuing

if(i<0||i>=size)



{

cerr<<"Errorinarraylimits:"

<
exit(1);

}

returnarr[i];

}

Thisslowsdownaprogram,foritrequiresevaluatinganif

statementeverytimetheprogramaccessesanarrayelement.

Butitaddssafety,preventingaprogramfromplacingavaluein

the2000thelementofa5-elementarray.

AswiththeStringclass,weneedaconstversionofthe[]

operatortoallowread-onlyaccessforconstantArrayDb

objects:

constdouble&ArrayDb::operator[](inti)const

{

//checkindexbeforecontinuing

if(i<0||i>=size)

{

cerr<<"Errorinarraylimits:"



<
exit(1);

}

returnarr[i];

}

Thecompilerwillselecttheconstversionofoperator[]()for

usewithconstArrayDbobjectsandusetheotherversionfor

non-constArrayDbobjects.

Listing14.1showstheheaderfilefortheArrayDbclass.For

extraconvenience,theclassdefinitionincludesanAverage()

methodthatreturnstheaverageofthearrayelements.



Listing14.1arraydb.h



//arraydb.h--arrayclass

#ifndefARRAYDB_H_

#defineARRAYDB_H_

#include

usingnamespacestd;



classArrayDb



{

private:



unsignedintsize;//numberofarrayelem



double*arr;//addressoffirstele

public:

ArrayDb();//defaultconstructor

//createanArrayDbofnelements,seteachtoval

explicitArrayDb(unsignedintn,doubleval=0.0);

//createanArrayDbofnelements,initializetoarraypn

ArrayDb(constdouble*pn,unsignedintn);

ArrayDb(constArrayDb&a);//copyconstructor

virtual~ArrayDb();//destructor



unsignedintArSize()const{returnsize;}//returnsarray



doubleAverage()const;//returnarrayaverage

//overloadedoperators

double&operator[](inti);//arrayindexing

constdouble&operator[](inti)const;//arrayindexing

ArrayDb&operator=(constArrayDb&a);



friendostream&operator<<(ostream&os,constArrayDb&a

};



#endif



CompatibilityNote

Olderimplementationsdon'tsupporttheexplicitkeyword.



Onepointofinterestisthatoneoftheconstructorsuses

explicit:

explicitArrayDb(unsignedintn,doubleval=0.0);

Aconstructorthatcanbecalledwithoneargument,recall,

servesasanimplicitconversionfunctionfromtheargument

typetotheclasstype.Inthiscase,thefirstargument

representsthenumberofelementsinthearrayratherthana

valueforthearray,sohavingtheconstructorserveasanintto-ArrayDbconversionfunctiondoesnotmakesense.Using

explicitturnsoffimplicitconversions.Ifthiskeywordwere

omitted,thencodelikethefollowingwouldbepossible:

ArrayDbdoh(20,100);//arrayof20elements,eachsetto100



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

Chapter 14. REUSING CODE IN C++

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

×