Tải bản đầy đủ - 0 (trang)
Chapter 9. MEMORY MODELS AND NAMESPACES

Chapter 9. MEMORY MODELS AND NAMESPACES

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

SeparateCompilation

C++,likeC,allowsandevenencouragesyoutolocatethe

componentfunctionsofaprograminseparatefiles.AsChapter

1,"GettingStarted,"describes,youcancompilethefiles

separatelyandthenlinkthemintothefinalexecutable

program.(AC++compilertypicallycompilesprogramsandalso

managesthelinkerprogram.)Ifyoumodifyjustonefile,you

canrecompilejustthatonefileandthenlinkittothepreviously

compiledversionsoftheotherfiles.Thisfacilitymakesiteasier

tomanagelargeprograms.Furthermore,mostC++

environmentsprovideadditionalfacilitiestohelpwiththe

management.UnixandLinuxsystems,forexample,havethe

makeprogram;itkeepstrackofwhichfilesaprogramdepends

uponandwhentheywerelastmodified.Ifyourunmakeandit

detectsyou'vechangedoneormoresourcefilessincethelast

compilation,makerememberstheproperstepsneededto

reconstitutetheprogram.TheBorlandC++,MicrosoftVisual

C++,andMetrowerksCodeWarriorIDEs(integrated

developmentenvironments)providesimilarfacilitieswiththeir

Projectmenus.

Let'slookatasimpleexample.Insteadoflookingat

compilationdetails,whichdependontheimplementation,let's

concentrateonmoregeneralaspects,suchasdesign.

Suppose,forexample,youdecidetobreakuptheprogramin

Listing7.11byplacingthefunctionsinaseparatefile.That

listing,recall,convertedrectangularcoordinatestopolar

coordinatesandthendisplayedtheresult.Youcan'tsimplycut

theoriginalfileonadottedlineaftertheendofmain().The

problemisthatmain()andtheothertwofunctionsallusethe

samestructuredeclarations,soyouneedtoputthe

declarationsinbothfiles.Simplytypingtheminisaninvitation

toerr.Evenifyoucopythestructuredeclarationscorrectly,you



havetoremembertomodifybothsetsofdeclarationsifyou

makechangeslater.Inshort,spreadingaprogramover

multiplefilescreatesnewproblems.

Whowantsmoreproblems?ThedevelopersofCandC++

didn't,sothey'veprovidedthe#includefacilitytodealwith

thissituation.Insteadofplacingthestructuredeclarationsin

eachfile,youcanplacetheminaheaderfileandtheninclude

thatheaderfileineachsourcecodefile.Thatway,ifyoumodify

thestructuredeclaration,youcandosojustonce,intheheader

file.Also,youcanplacethefunctionprototypesintheheader

file.Thus,youcandividetheoriginalprogramintothreeparts:

Aheaderfilethatcontainsthestructuredeclarationsand

prototypesforfunctionsusingthosestructures

Asourcecodefilethatcontainsthecodeforthestructurerelatedfunctions

Asourcecodefilethatcontainsthecodethatcallsupon

thosefunctions

Thisisausefulstrategyfororganizingaprogram.If,for

example,youwriteanotherprogramthatusesthosesame

functions,justincludetheheaderfileandaddthefunctionfile

totheprojectormakelist.Also,thisorganizationreflectsthe

OOPapproach.Onefile,theheaderfile,containsthedefinition

oftheuser-definedtypes.Asecondfilecontainsthefunction

codeformanipulatingtheuser-definedtypes.Together,they

formapackageyoucanuseforavarietyofprograms.

Don'tputfunctiondefinitionsorvariabledeclarationsintoa

headerfile.Itmightworkforasimplesetup,butusuallyit

leadstotrouble.Forexample,ifyouhadafunctiondefinitionin

aheaderfileandthenincludedtheheaderfileintwootherfiles

thatarepartofasingleprogram,you'dwindupwithtwo



definitionsofthesamefunctioninasingleprogram,whichisan

error,unlessthefunctionisinline.Herearesomethings

commonlyfoundinheaderfiles:

Functionprototypes

Symbolicconstantsdefinedusing#defineorconst

Structuredeclarations

Classdeclarations

Templatedeclarations

Inlinefunctions

It'sokaytoputstructuredeclarationsinaheaderfile,forthey

don'tcreatevariables;theyjusttellthecompilerhowtocreate

astructurevariablewhenyoudeclareoneinasourcecodefile.

Similarly,templatedeclarationsaren'tcodetobecompiled;

theyareinstructionstothecompileronhowtogenerate

functiondefinitionstomatchfunctioncallsfoundinthesource

code.Datadeclaredconstandinlinefunctionshavespecial

linkageproperties(comingupsoon)thatallowthemtobe

placedinheaderfileswithoutcausingproblems.

Listings9.1,9.2,and9.3showtheresultofdividingListing

7.11intoseparateparts.Notethatweuse"coordin.h"instead

ofwhenincludingtheheaderfile.Ifthefilename

isenclosedinanglebrackets,theC++compilerlooksatthe

partofthehostsystem'sfilesystemthatholdsthestandard

headerfiles.Butifthefilenameisenclosedindoublequotation

marks,thecompilerfirstlooksatthecurrentworkingdirectory

oratthesourcecodedirectory(orsomesuchchoice,depending

uponthecompiler).Ifitdoesn'tfindtheheaderfilethere,it



thenlooksinthestandardlocation.Sousequotationmarks,not

anglebrackets,whenincludingyourownheaderfiles.

Figure9.1outlinesthestepsforputtingthisprogramtogether

onaUnixsystem.NotethatyoujustgivetheCCcompile

commandandtheotherstepsfollowautomatically.Theg++

command-linecompilerandtheBorlandC++command-line

compiler(bcc32.exe)alsobehavethatway.SymantecC++,

BorlandC++,TurboC++,MetrowerksCodeWarrior,Watcom

C++,andMicrosoftVisualC++gothroughessentiallythesame

steps,but,asoutlinedinChapter1,youinitiatetheprocess

differently,usingmenusthatletyoucreateaprojectand

associatesourcecodefileswithit.Notethatyouonlyadd

sourcecodefiles,notheaderfilestoprojects.That'sbecause

the#includedirectivemanagestheheaderfiles.Also,don't

use#includetoincludesourcecodefiles,asthatcanleadto

multipledeclarations.



Figure9.1.CompilingamultifileC++programon

aUnixsystem.



Caution

InIntegratedDevelopmentEnvironments,don'taddheaderfilestothe

projectlist,anddon'tuse#includetoincludesourcecodefilesinother

sourcecodefiles.



Listing9.1coordin.h



//coordin.h--structuretemplatesandfunctionprototypes

//structuretemplates

#ifndefCOORDIN_H_

#defineCOORDIN_H_



structpolar

{

doubledistance;//distancefromorigin

doubleangle;//directionfromorigin

};

structrect

{

doublex;//horizontaldistancefromorigin

doubley;//verticaldistancefromorigin

};

//prototypes

polarrect_to_polar(rectxypos);

voidshow_polar(polardapos);



#endif



HeaderFileManagement

Youshouldincludeaheaderfilejustonceinafile.Thatmightseemto

beaneasythingtoremember,butit'spossibletoincludeaheaderfile

severaltimeswithoutknowingyoudidso.Forexample,youmightusea

headerfilethatincludesanotherheaderfile.There'sastandardC/C++

techniqueforavoidingmultipleinclusionsofheaderfiles.It'sbasedon

thepreprocessor#ifndef(forifnotdefined)directive.Acodesegment

like

#ifndefCOORDIN_H_

...

#endif

meansprocessthestatementsbetweenthe#ifndefand#endifonlyif

thenameCOORDIN_H_hasnotbeendefinedpreviouslybythe

preprocessor#definedirective.

Normally,youusethe#definestatementtocreatesymbolicconstants,

asinthefollowing:

#defineMAXIMUM4096

Butsimplyusing#definewithanameisenoughtoestablishthata

nameisdefined,asinthefollowing:

#defineCOORDIN_H_

Thetechnique,whichListing9.1uses,istowrapthefilecontentsinan

#ifndef:

#ifndefCOORDIN_H_

#defineCOORDIN_H_

//placeincludefilecontentshere



#endif

Thefirsttimethecompilerencountersthefile,thenameCOORDIN_H_

shouldbeundefined.(Wechoseanamebasedontheincludefilename

withafewunderscorecharacterstossedinsoastocreateaname

unlikelytobedefinedelsewhere.)Thatbeingthecase,thecompiler

looksatthematerialbetweenthe#ifndefandthe#endif,whichis

whatwewant.Intheprocessoflookingatthematerial,thecompiler

readsthelinedefiningCOORDIN_H_.Ifitthenencountersasecond

inclusionofcoordin.hinthesamefile,thecompilernotesthat

COORDIN_H_isdefinedandskipstothelinefollowingthe#endif.Note

thatthismethoddoesn'tkeepthecompilerfromincludingafiletwice.

Instead,itmakesitignorethecontentsofallbutthefirstinclusion.

MostofthestandardCandC++headerfilesusethisscheme.



Listing9.2file1.cpp



//file1.cpp--exampleofatwo-fileprogram

#include



#include"coordin.h"//structuretemplates,functionprototype

usingnamespacestd;

intmain()

{

rectrplace;

polarpplace;



cout<<"Enterthexandyvalues:";

while(cin>>rplace.x>>rplace.y)//slickuseofcin

{

pplace=rect_to_polar(rplace);

show_polar(pplace);

cout<<"Nexttwonumbers(qtoquit):";

}

cout<<"Bye!\n";

return0;

}



Listing9.3file2.cpp



//file2.cpp--containsfunctionscalledinfile1.cpp

#include

#include



#include"coordin.h"//structuretemplates,functionprototype

usingnamespacestd;



//convertrectangulartopolarcoordinates

polarrect_to_polar(rectxypos)

{

polaranswer;



answer.distance=

sqrt(xypos.x*xypos.x+xypos.y*xypos.y);

answer.angle=atan2(xypos.y,xypos.x);

returnanswer;//returnsapolarstructure

}



//showpolarcoordinates,convertingangletodegrees

voidshow_polar(polardapos)

{

constdoubleRad_to_deg=57.29577951;



cout<<"distance="<
cout<<",angle="<


cout<<"degrees\n";

}

Bytheway,althoughwe'vediscussedseparatecompilationin

termsoffiles,thelanguagedescriptionusestheterm

translationunitinsteadoffileinordertopreservegreater

generality;thefilemetaphorisnottheonlypossiblewayto

organizeinformationforacomputer.



RealWorldNote:MultipleLibraryLinking

TheC++Standardallowseachcompilerdesignerthelatitudeto

implementnamedecorationormangling(seetheRealWorldNoteon

namedecorationinChapter8,"AdventuresinFunctions")asitseesfit,

soyoushouldbeawarethatbinarymodules(object-codefiles)created

withdifferentcompilerswill,mostlikely,notlinkproperly.Thatis,the

twocompilerswillgeneratedifferentdecoratednamesforthesame

function.Thisnamedifferencewillpreventthelinkerfrommatchingthe

functioncallgeneratedbyonecompilerwiththefunctiondefinition

generatedbyasecondcompiler.Whenattemptingtolinkcompiled

modules,makesurethateachobjectfileorlibrarywasgeneratedwith

thesamecompiler.Ifyouareprovidedwiththesourcecode,youcan

usuallyresolvelinkerrorsbyrecompilingthesourcewithyourcompiler.



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

Chapter 9. MEMORY MODELS AND NAMESPACES

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

×