C++14QuickSyntaxReference
Copyright©2015byMikaelOlsson
Thisworkissubjecttocopyright.AllrightsarereservedbythePublisher,whetherthewholeorpartofthematerialisconcerned,specificallytherightsoftranslation,reprinting,reuseofillustrations,recitation,broadcasting,reproductiononmicrofilmsorinanyotherphysicalway,andtransmissionorinformationstorageandretrieval,electronicadaptation,computersoftware,orbysimilarordissimilarmethodologynowknownorhereafterdeveloped.Exemptedfromthislegalreservationarebriefexcerptsinconnectionwithreviewsorscholarlyanalysisormaterialsuppliedspecificallyforthepurposeofbeingenteredandexecutedonacomputersystem,forexclusiveusebythepurchaserofthework.DuplicationofthispublicationorpartsthereofispermittedonlyundertheprovisionsoftheCopyrightLawofthePublisher’slocation,initscurrentversion,andpermissionforusemustalwaysbeobtainedfromSpringer.PermissionsforusemaybeobtainedthroughRightsLinkattheCopyrightClearanceCenter.ViolationsareliabletoprosecutionundertherespectiveCopyrightLaw.
ISBN-13(pbk):978-1-4842-1726-9
ISBN-13(electronic):978-1-4842-1727-6
Trademarkednames,logos,andimagesmayappearinthisbook.Ratherthanuseatrademarksymbolwitheveryoccurrenceofatrademarkedname,logo,orimageweusethenames,logos,andimagesonlyinaneditorialfashionandtothebenefitofthetrademarkowner,withnointentionofinfringementofthetrademark.
Theuseinthispublicationoftradenames,trademarks,servicemarks,andsimilarterms,eveniftheyarenotidentifiedassuch,isnottobetakenasanexpressionofopinionastowhetherornottheyaresubjecttoproprietaryrights.
Whiletheadviceandinformationinthisbookarebelievedtobetrueandaccurateatthedateofpublication,neithertheauthorsnortheeditorsnorthepublishercanacceptanylegalresponsibilityforanyerrorsoromissionsthatmaybemade.Thepublishermakesnowarranty,expressorimplied,withrespecttothematerialcontainedherein.
ManagingDirector:WelmoedSpahrLeadEditor:SteveAnglinDevelopmentalEditor:MatthewMoodieEditorialBoard:SteveAnglin,LouiseCorrigan,JonathanGennick,RobertHutchinson,MichelleLowman,JamesMarkham,
SusanMcDermott,MatthewMoodie,JeffreyPepper,DouglasPundick,BenRenow-Clarke,GwenanSpearingCopyEditor:KarenJamesonCoordinatingEditor:MarkPowersCompositor:SPiGlobalIndexer:SPiGlobalArtist:SPiGlobal
DistributedtothebooktradeworldwidebySpringerScience+BusinessMediaNewYork,233SpringStreet,6thFloor,NewYork,NY10013.Phone1-800-SPRINGER,fax(201)348-4505,[email protected],orvisitwww.springeronline.com.ApressMedia,LLCisaCaliforniaLLCandthesolemember(owner)isSpringerScience+BusinessMediaFinanceInc(SSBMFinanceInc).SSBMFinanceIncisaDelaware corporation.
Forinformationontranslations,[email protected],orvisitwww.apress.com.
ApressandfriendsofEDbooksmaybepurchasedinbulkforacademic,corporate,orpromotionaluse.eBookversionsandlicensesarealsoavailableformosttitles.Formoreinformation,referenceourSpecialBulkSales–eBookLicensingwebpageatwww.apress.com/bulk-sales.
Anysourcecodeorothersupplementarymaterialreferencedbytheauthorinthistextisavailabletoreadersatwww.apress.com/9781484217269.Fordetailedinformationabouthowtolocateyourbook’ssourcecode,gotowww.apress.com/source-code/.
ContentsataGlance
AbouttheAuthorIntroduction
Chapter1:HelloWorldChapter2:CompileandRunChapter3:VariablesChapter4:OperatorsChapter5:PointersChapter6:ReferencesChapter7:ArraysChapter8:StringChapter9:ConditionalsChapter10:LoopsChapter11:FunctionsChapter12:ClassChapter13:ConstructorChapter14:InheritanceChapter15:OverridingChapter16:AccessLevelsChapter17:StaticChapter18:EnumChapter19:StructandUnionChapter20:OperatorOverloadingChapter21:CustomConversionsChapter22:NamespacesChapter23:ConstantsChapter24:PreprocessorChapter25:ExceptionHandling
Contents
AbouttheAuthorIntroduction
Chapter1:HelloWorldChoosinganIDECreatingaProjectAddingaSourceFileHelloWorldUsingNamespaceIntelliSense
Chapter2:CompileandRunVisualStudioCompilationConsoleCompilationComments
Chapter3:VariablesDataTypesDeclaringVariablesAssigningVariablesVariableScopeIntegerTypesSignedandUnsignedIntegersNumericLiteralsFloating-PointTypesLiteralSuffixesCharTypeBoolType
Chapter4:OperatorsArithmeticOperatorsAssignmentOperatorsCombinedAssignmentOperatorsIncrementandDecrementOperatorsComparisonOperatorsLogicalOperatorsBitwiseOperatorsOperatorPrecedence
Chapter5:PointersCreatingPointersDereferencingPointersPointingtoaPointerDynamicAllocationNullPointer
Chapter6:ReferencesCreatingReferencesReferencesandPointersReferenceandPointerGuidelineRvalueReference
Chapter7:ArraysArrayDeclarationandAllocationArrayAssignmentMulti-dimensionalArraysDynamicArraysArraySize
Chapter8:StringStringCombiningEscapeCharactersStringCompare
StringFunctionsStringEncodings
Chapter9:ConditionalsIfStatementSwitchStatementTernaryOperator
Chapter10:LoopsWhileLoopDo-whileLoopForLoopBreakandContinueGotoStatement
Chapter11:FunctionsDefiningFunctionsCallingFunctionsFunctionParametersDefaultParameterValuesFunctionOverloadingReturnStatementForwardDeclarationPassbyValuePassbyReferencePassbyAddressReturnbyValue,ReferenceorAddressInlineFunctionsAutoandDecltypeLambdaFunctions
Chapter12:ClassClassMethodsInlineMethods
ObjectCreationAccessingObjectMembersForwardDeclaration
Chapter13:ConstructorConstructorOverloadingThiskeywordFieldInitializationDefaultConstructorDestructorSpecialMemberFunctionsObjectInitializationDirectInitializationValueInitializationCopyInitializationNewInitializationAggregateInitializationUniformInitialization
Chapter14:InheritanceUpcastingDowncastingConstructorInheritanceMultipleInheritance
Chapter15:OverridingHidingDerivedMembersOverridingDerivedMembersBaseClassScoping
Chapter16:AccessLevelsPrivateAccessProtectedAccessPublicAccess
AccessLevelGuidelineFriendClassesandFunctionsPublic,ProtectedandPrivateInheritance
Chapter17:StaticStaticFieldsStaticMethodsStaticLocalVariablesStaticGlobalVariables
Chapter18:EnumEnumExampleEnumConstantValuesEnumConversionsEnumScopeStronglyTypedEnums
Chapter19:StructandUnionStructDeclaratorListUnionAnonymousUnion
Chapter20:OperatorOverloadingOperatorOverloadingExampleBinaryOperatorOverloadingUnaryOperatorOverloadingOverloadableOperators
Chapter21:CustomConversionsImplicitConversionConstructorExplicitConversionConstructorConversionOperatorsExplicitConversionOperators
Chapter22:Namespaces
AccessingNamespaceMembersNestingNamespacesImportingNamespacesNamespaceMemberImportNamespaceAliasTypeAliasIncludingNamespaceMembers
Chapter23:ConstantsConstantVariablesConstantPointersConstantReferencesConstantObjectsConstantMethodsConstantReturnTypeandParametersConstantFieldsConstantExpressionsConstantGuideline
Chapter24:PreprocessorIncludingSourceFilesDefineUndefinePredefinedMacrosMacroFunctionsConditionalCompilationCompileifDefinedErrorLinePragmaAttributes
Chapter25:ExceptionHandling
ThrowingExceptionsTry-catchstatementRe-throwingExceptionsExceptionSpecificationExceptionClass
Chapter26:TypeConversionsImplicitConversionsExplicitConversions
C++casts
StaticCastReinterpretCastConstCastC-styleandNew-StyleCastsDynamicCastDynamicCastExamplesDynamicorStaticCast
Chapter27:TemplatesFunctionTemplatesCallingFunctionTemplatesMultipleTemplateParametersClassTemplatesNon-TypeParametersDefaultTypesandValuesClassTemplateSpecializationFunctionTemplateSpecializationVariableTemplatesVariadicTemplates
Chapter28:HeadersWhytoUseHeadersUsingHeaders
AbouttheAuthor
MikaelOlssonisaprofessionalwebentrepreneur,programmer,andauthor.HeworksforanR&DcompanyinFinlandwherehespecializesinsoftwaredevelopment.Inhissparetimehewritesbooksandcreateswebsitesthatsummarizevariousfieldsofinterest.Thebookshewritesarefocusedonteachingtheirsubjectinthemostefficientwaypossible,byexplainingonlywhatisrelevantandpracticalwithoutanyunnecessaryrepetitionortheory.
Introduction
TheC++programminglanguageisageneralpurposemulti-paradigmlanguagecreatedbyBjarneStroustrup.Developmentofthelanguagestartedin1979underthename“Cwithclasses.”Asthenameimplies,itwasanextensionoftheClanguagewiththeadditionalconceptofclasses.StroustrupwantedtocreateabetterCthatcombinedthepowerandefficiencyofCwithhigh-levelabstractionstobettermanagelargedevelopmentprojects.TheresultinglanguagewasrenamedtoC++(C-Plus-Plus)in1983.AsadeliberatedesignfeatureC++maintainscompatibilitywithC,andsomostCcodecaneasilybemadetocompileinC++.
TheintroductionofC++becameamajormilestoneinthesoftwareindustryasawidelysuccessfullanguageforbothsystemandapplicationdevelopment.Systemprogramminginvolvessoftwarethatcontrolsthecomputerhardwaredirectly,suchasdrivers,operatingsystems,andsoftwareforembeddedmicroprocessors.Theseareasremainthecoredomainofthelanguage,whereresourcesarescarceandcomeatapremium.C++isalsowidelyusedforwritingapplications,whichrunontopofsystemsoftware,especiallyhigh-performancesoftwaresuchasgames,databases,andresource-demandingdesktopapplications.Despitetheintroductionofmanymodern,high-levellanguagesinthisdomain–suchasJava,C#,andPython–C++stillholdsitsownandoverallremainsoneofthemostpopularandinfluentialprogramminglanguagesinusetoday.
ThereareseveralreasonsforthewidespreadadoptionofC++.Theforemostreasonwastherarecombinationofbothhigh-levelandlow-levelabstractionsfromthehardware.Thelow-levelefficiencywasinheritedfromC,andthehigh-levelconstructscameinpartfromasimulationlanguagecalledSimula.ThiscombinationmakesitpossibletowriteC++softwarewiththestrengthofbothapproaches.Anotherstrongpointofthelanguageisthatitdoesnotimposeaspecificprogrammingparadigmonitsusers.Itisdesignedtogivetheprogrammeralotoffreedombysupportingmanydifferentprogrammingstylesorparadigms,suchasprocedural,object-oriented,andgenericprogramming.
C++isupdatedandmaintainedbytheC++standardscommittee.In1998,thefirstinternationalstandardwaspublished,knowninformallyasC++98.Thelanguagehassinceundergonethreemorerevisionswithfurtherextensions,includingC++03;C++11;andmostrecently,C++14,whichisthelatestISOstandardfortheC++programminglanguagereleasedin2014.
CHAPTER1
HelloWorld
ChoosinganIDETobegindevelopinginC++youneedatexteditorandaC++compiler.YoucangetbothatthesametimebyinstallinganIntegratedDevelopmentEnvironment(IDE)thatincludessupportforC++.AgoodchoiceisMicrosoft’sVisualStudioCommunityEdition,whichisafreeversionofVisualStudiothatisavailablefromMicrosoft’swebsite.1ThisIDEhasbuilt-insupportfortheC++11standardandalsoincludesmanyfeaturesofC++14asofthe2015version.
Twootherpopularcross-platformIDEsincludeNetBeansandEclipseCDT.Alternatively,youcandevelopusingasimpletexteditor–suchasNotepad–althoughthisislessconvenientthanusinganIDE.Ifyouchoosetodoso,justcreateanemptydocumentwitha.cppfileextensionandopenitintheeditorofyourchoice.
CreatingaProjectAfterinstallingVisualStudio,goaheadandlaunchtheprogram.Youthenneedtocreateaproject,whichwillmanagetheC++sourcefilesandotherresources.GotoFile New ProjectinVisualStudiotodisplaytheNewProjectwindow.FromthereselecttheVisualC++templatetypeintheleftframe.ThenselecttheWin32ConsoleApplicationtemplateintherightframe.Atthebottomofthewindowyoucanconfigurethenameandlocationoftheproject.Whenyouarefinished,clicktheOKbuttonandanotherdialogboxwillappeartitledWin32ApplicationWizard.Clicknextandacoupleofapplicationsettingswillbedisplayed.LeavetheapplicationtypeasConsoleapplicationandchecktheEmptyprojectcheckbox.ThenclickFinishtoletthewizardcreateyouremptyproject.
AddingaSourceFileYouhavenowcreatedaC++project.IntheSolutionExplorerpane(View SolutionExplorer)youcanseethattheprojectconsistsofthreeemptyfolders:HeaderFiles,ResourceFilesandSourceFiles.RightclickontheSourceFilesfolderandselectAdd NewItem.FromtheAddNewItemdialogboxchoosetheC++File(.cpp)template.
Givethissourcefilethename“MyApp”andclicktheAddbutton.Anemptycppfilewillnowbe
addedtoyourprojectandalsoopenedforyou.
HelloWorldThefirstthingtoaddtothesourcefileisthemainfunction.Thisistheentrypointoftheprogram,andthecodeinsideofthecurlybracketsiswhatwillbeexecutedwhentheprogramruns.Thebrackets,alongwiththeircontent,isreferredtoasacodeblock,orjustablock.
intmain(){}
Thefirstapplicationwillsimplyoutputthetext“HelloWorld”tothescreen.Beforethiscanbedonetheiostreamheaderneedstobeincluded.Thisheaderprovidesinputandoutputfunctionalityfortheprogram,andisoneofthestandardlibraryfilesthatcomewithallC++compilers.Whatthe#includedirectivedoesiseffectivelytoreplacethelinewitheverythinginthespecifiedheaderbeforethefileiscompiledintoanexecutable.
#include<iostream>intmain(){}
Withiostreamincludedyougainaccesstoseveralnewfunctions.Thesearealllocatedinthestandardnamespacecalledstd,whichyoucanexaminebyusingadoublecolon,alsocalledthescoperesolutionoperator(::).AftertypingthisinVisualStudio,theIntelliSensewindowwillautomaticallyopen,displayingwhatthenamespacecontains.Amongthemembersyoufindthecoutstream,whichisthestandardoutputstreaminC++thatwillbeusedtoprinttexttoaconsolewindow.Itusestwoless-thansignsknownastheinsertionoperator(<<)toindicatewhattooutput.Thestringcanthenbespecified,delimitedbydoublequotes,andfollowedbyasemicolon.ThesemicolonisusedinC++tomarktheendofallstatements.
#include<iostream>
intmain(){std::cout<<"HelloWorld";}
UsingNamespaceTomakethingsabiteasieryoucanaddalinespecifyingthatthecodefileusesthestandardnamespace.Youthennolongerhavetoprefixcoutwiththenamespace(std::)sinceitisnowusedbydefault.
#include<iostream>usingnamespacestd;
intmain(){
cout<<"HelloWorld";}
IntelliSenseWhenwritingcodeinVisualStudio,awindowcalledIntelliSensewillpopupwherevertherearemultiplepredeterminedalternativesfromwhichtochoose.ThiswindowcanbealsobroughtupmanuallyatanytimebypressingCtrl+Spacetoprovidequickaccesstoanycodeentitiesyouareabletousewithinyourprogram.Thisisaverypowerfulfeaturethatyoushouldlearntomakegooduseof.
________________1http://www.microsoft.com/visualstudio
CHAPTER2
CompileandRun
VisualStudioCompilationContinuingfromthelastchapter,theHelloWorldprogramisnowcompleteandreadytobecompiledandrun.YoucandothisbygoingtotheDebugmenuandclickingonStartWithoutDebugging(Ctrl+F5).VisualStudiothencompilesandrunstheapplicationwhichdisplaysthetextinaconsolewindow.
IfyouselectStartDebugging(F5)fromtheDebugmenuinstead,theconsolewindowdisplayingHelloWorldwillcloseassoonasthemainfunctionisfinished.Topreventthisyoucanaddacalltothecin::getfunctionattheendofmain.Thisfunction,belongingtotheconsoleinputstream,willreadinputfromthekeyboarduntilthereturnkeyispressed.
#include<iostream>usingnamespacestd;intmain(){cout<<"HelloWorld";cin.get();}
ConsoleCompilationAsanalternativetousinganIDEyoucanalsocompilesourcefilesfromaterminalwindowaslongasyouhaveaC++compiler.1Forexample,onaLinuxmachineyoucanusetheGNUC++compiler,whichisavailableonvirtuallyallUnixsystems,includingLinuxandtheBSDfamily,aspartoftheGNUCompilerCollection(GCC).ThiscompilercanalsobeinstalledonWindowsbydownloadingMinGWoronMacaspartoftheXcodedevelopmentenvironment.
TousetheGNUcompileryoutypeitsname"g++"inaterminalwindowandgiveittheinputandoutputfilenamesasarguments.Itthenproducesanexecutablefile,whichwhenrungivesthesameresultasonecompiledunderWindowsinVisualStudio.
g++MyApp.cpp-oMyApp.exe./MyApp.exeHelloWorld
CommentsCommentsareusedtoinsertnotesintothesourcecode.Theyhavenoeffectontheendprogramandaremeantonlytoenhancethereadabilityofthecode,bothforyouandforotherdevelopers.C++hastwokindsofcommentnotations-single-lineandmulti-line.Thesingle-linecommentstartswith//andextendstotheendoftheline.
//single-linecomment
Themulti-linecommentmayspanmorethanonelineandisdelimitedby/*and*/.
/*multi-linecomment*/
Keepinmindthatwhitespacecharacters–suchascomments,spaces,andtabs–aregenerallyignoredbythecompiler.Thisallowsyoualotoffreedominhowtoformatyourcode.
________________1http://www.stroustrup.com/compilers.html
CHAPTER3
Variables
Variablesareusedforstoringdataduringprogramexecution.
DataTypesDependingonwhatdatayouneedtostorethereareseveralkindsofbuilt-indatatypes.Theseareoftencalledfundamentaldatatypesorprimitives.Theinteger(wholenumber)typesareshort,int,long,andlonglong.Thefloat,doubleandlongdoubletypesarefloating-point(realnumber)types.Thechartypeholdsasinglecharacterandthebooltypecontainseitheratrueorfalsevalue.
DataType Size(byte) Description
char 1 Integerorcharacter
short 2
int 4 Integer
long 4or8
longlong 8
float 4
double 8 Floating-pointnumber
longdouble 8or16
bool 1 Booleanvalue
InC++,theexactsizeandrangeofdatatypesarenotfixed.Insteadtheyaredependentonthesystemforwhichtheprogramiscompiled.Thesizesshowninthetableabovearethosefoundonmost32-bitsystemsandaregiveninC++bytes.AbyteinC++istheminimumaddressableunitofmemory,whichisguaranteedtobeatleast8bits,butmightalsobe16or32bitsdependingonthesystem.Bydefinition,acharinC++is1byteinsize.Furthermore,theinttypewillhavethesamesizeastheprocessor’swordsize,sofora32-bitsystemtheintegerswillbe32bitsinsize.Eachintegertypeinthetablemustalsobeatleastaslargeastheoneprecedingit.Thesameappliestofloating-pointtypeswhereeachonemustprovideatleastasmuchprecisionastheprecedingone.
DeclaringVariablesTodeclare(create)avariableyoustartwiththedatatypeyouwantthevariabletoholdfollowedbyanidentifier,whichisthenameofthevariable.Thenamecanconsistofletters,numbersandunderscores,butitcannotstartwithanumber.Italsocannotcontainspacesorspecialcharactersandmustnotbeareservedkeyword.
intmyInt;//correctint_myInt32;//correctint32Int;//incorrect(startswithnumber)intInt32;//incorrect(containsspace)intInt@32;//incorrect(containsspecialcharacter)intnew;//incorrect(reservedkeyword)
AssigningVariablesToassignavaluetoadeclaredvariabletheequalsignisused,whichiscalledtheassignmentoperator(=).
myInt=50;
Thedeclarationandassignmentcanbecombinedintoasinglestatement.Whenavariableisassignedavalueitthenbecomesdefined.
intmyInt=50;
Atthesametimethatthevariableisdeclaredthereisanalternativewayofassigning,orinitializing,itbyenclosingthevalueinparentheses.Thisisknownasconstructorinitializationandisequivalenttothestatementabove.
intmyAlt(50);
Ifyouneedtocreatemorethanonevariableofthesametypethereisashorthandwayofdoingitusingthecommaoperator(,).
intx=1,y=2,z;
Onceavariablehasbeendefined(declaredandassigned),youcanuseitbysimplyreferencingthevariable’sname:forexample,toprintit.
std::cout<<x<<y;//"12"
VariableScopeThescopeofavariablereferstotheregionofcodewithinwhichitispossibletousethatvariable.VariablesinC++maybedeclaredbothgloballyandlocally.Aglobalvariableisdeclaredoutsideofany
codeblocksandisaccessiblefromanywhereafterithasbeendeclared.Alocalvariable,ontheotherhand,isdeclaredinsideofafunctionandwillonlybeaccessiblewithinthatfunctionafterithasbeendeclared.Thelifetimeofalocalvariableisalsolimited.Aglobalvariablewillremainallocatedforthedurationoftheprogram,whilealocalvariablewillbedestroyedwhenitsfunctionhasfinishedexecuting.
intglobalVar;//globalvariableintmain(){intlocalVar;}//localvariable
Thedefaultvaluesforthesevariablesarealsodifferent.Globalvariablesareautomaticallyinitializedtozerobythecompiler,whereaslocalvariablesarenotinitializedatall.Uninitializedlocalvariableswillthereforecontainwhatevergarbageisalreadypresentinthatmemorylocation.
intglobalVar;//initializedto0
intmain(){intlocalVar;//uninitialized}
Usinguninitializedvariablesisacommonprogrammingmistakethatcanproduceunexpectedresults.Itisthereforeagoodideatoalwaysgiveyourlocalvariablesaninitialvaluewhentheyaredeclared.
intmain(){intlocalVar=0;//initializedto0}
IntegerTypesTherearefourintegertypesyoucanusedependingonhowlargeanumberyouneedthevariabletohold.
charmyChar=0;//-128to+127shortmyShort=0;//-32768to+32767intmyInt=0;//-2^31to+2^31-1longmyLong=0;//-2^31to+2^31-1
C++11standardizedafifthintegertype,longlong,whichisguaranteedtobeatleast64-bitslarge.ManycompilersstartedtosupportthisdatatypewellbeforetheC++11standardwascomplete,includingtheMicrosoftC++compiler.
longlongmyL2=0;//-2^63to+2^63-1
Todeterminetheexactsizeofadatatypeyoucanusethesizeofoperator.Thisoperatorreturnsthenumberofbytesthatadatatypeoccupiesinthesystemyouarecompilingfor.
std::cout<<sizeof(myChar)//1byte(perdefinition)<<sizeof(myShort)//2<<sizeof(myInt)//4
<<sizeof(myLong)//4<<sizeof(myL2);//8
Fixed-sizedintegertypeswereaddedinC++11.Thesetypesbelongtothestdnamespaceandcanbeincludedthroughthecstdintstandardlibraryheader.
#include<cstdint>usingnamespacestd;int8_tmyInt8=0;//8bitsint16_tmyInt16=0;//16bitsint32_tmyInt32=0;//32bitsint64_tmyInt64=0;//64bits
SignedandUnsignedIntegersBydefault,allthenumbertypesinMicrosoftC++aresignedandmaythereforecontainbothpositiveandnegativevalues.Toexplicitlydeclareavariableassignedthesignedkeywordcanbeused.
signedcharmyChar=0;//-128to+127signedshortmyShort=0;//-32768to+32767signedintmyInt=0;//-2^31to+2^31-1signedlongmyLong=0;//-2^31to+2^31-1signedlonglongmyL2=0;//-2^63to+2^63-1
Ifyouonlyneedtostorepositivevaluesyoucandeclareintegertypesasunsignedtodoubletheirupperrange.
unsignedcharmyChar=0;//0to255unsignedshortmyShort=0;//0to65535unsignedintmyInt=0;//0to2^32-1unsignedlongmyLong=0;//0to2^32-1unsignedlonglongmyL2=0;//0to2^64-1
Thesignedandunsignedkeywordsmaybeusedasstandalonetypes,whichareshortforsignedintandunsignedint.
unsigneduInt;//unsignedintsignedsInt;//signedint
Similarly,theshortandlongdatatypesareabbreviationsofshortintandlongint.
shortmyShort;//shortintlongmyLong;//longint
NumericLiterals
Inadditiontostandarddecimalnotation,integerscanalsobeassignedbyusingoctalorhexadecimalnotation.Octalliteralsusetheprefix“0”andhexadecimalliteralsstartwith“0x.”Bothnumbersbelowrepresentthesamenumber,whichindecimalnotationis50.
intmyOct=062;//octalnotation(0)intmyHex=0x32;//hexadecimalnotation(0x)
AsofC++14thereisabinarynotation,whichuses“0b”asitsprefix.Thisversionofthestandardalsoaddedadigitseparator(')whichcanmakeiteasiertoreadlongnumbers.Thebinarynumberbelowrepresents50indecimalnotation.
intmyBin=0b0011'0010;//binarynotation(0b)
Floating-PointTypesThefloating-pointtypescanstorerealnumberswithdifferentlevelsofprecision.
floatmyFloat;//~7digitsdoublemyDouble;//~15digitslongdoublemyLongDouble;//typicallysameasdouble
Theprecisionshownabovereferstothetotalnumberofdigitsinthenumber.Afloatcanaccuratelyrepresentabout7digits,whereasadoublecanhandlearound15ofthem.Tryingtoassignmorethan7digitstoafloatmeansthattheleastsignificantdigitswillgetroundedoff.
myFloat=12345.678;//roundedto12345.68
Floatsanddoublescanbeassignedbyusingeitherdecimalorexponentialnotation.Exponential(scientific)notationisusedbyaddingEorefollowedbythedecimalexponent.
myFloat=3e2;//3*10^2=300
LiteralSuffixesAnintegerliteral(constant)isnormallytreatedasanintbythecompiler,oralargertypeifneededtofitthevalue.Suffixescanbeaddedtotheliteraltochangethisevaluation.WithintegersthesuffixcanbeacombinationofUandL,forunsignedandlongrespectively.C++11alsoaddedtheLLsuffixforthelonglongtype.Theorderandcasingoftheselettersdonotmatter.
inti=10;longl=10L;unsignedlongul=10UL;
Afloating-pointliteralistreatedasadoubleunlessotherwisespecified.TheForfsuffixcanbeusedtospecifythataliteralisofthefloattypeinstead.Likewise,theLorlsuffixspecifiesthelongdoubletype.
floatf=1.23F;doubled=1.23;longdoubleld=1.23L;
Thecompilerimplicitlyconvertsliteralstowhichevertypeisnecessary,sothistypedistinctionforliteralsisusuallynotnecessary.IftheFsuffixisleftoutwhenassigningtoafloatvariable,thecompilermaygiveawarningsincetheconversionfromdoubletofloatinvolvesalossofprecision.
CharTypeThechartypeiscommonlyusedtorepresentASCIIcharacters.Suchcharacterconstantsareenclosedinsinglequotesandcanbestoredinavariableofchartype.
charc='x';//assigns120(ASCIIfor'x')
Theconversionbetweenthenumberstoredinthecharandthecharactershownwhenthecharisprintedoccursautomatically.
std::cout<<c;//prints'x'
Foranotherintegertypetobedisplayedasacharacterithastobeexplicitlycasttochar.Anexplicitcastisperformedbyplacingthedesireddatatypeinparenthesesbeforethevariableorconstantthatistobeconverted.
inti=c;//assigns120std::cout<<i;//prints120std::cout<<(char)i;//prints'x'
BoolTypeThebooltypecanstoreaBooleanvalue,whichisavaluethatcanonlybeeithertrueorfalse.Thesevaluesarespecifiedwiththetrueandfalsekeywords.
boolb=false;//trueorfalsevalue
CHAPTER4
Operators
Anumericaloperatorisasymbolthatmakestheprogramperformaspecificmathematicalorlogicalmanipulation.ThenumericaloperatorsinC++canbegroupedintofivetypes:arithmetic,assignment,comparison,logicalandbitwiseoperators.
ArithmeticOperatorsTherearethefourbasicarithmeticoperators,aswellasthemodulusoperator(%)whichisusedtoobtainthedivisionremainder.
intx=3+2;//5//additionx=3-2;//1//subtractionx=3*2;//6//multiplicationx=3/2;//1//divisionx=3%2;//1//modulus(divisionremainder)
Noticethatthedivisionsigngivesanincorrectresult.Thisisbecauseitoperatesontwointegervaluesandwillthereforetruncatetheresultandreturnaninteger.Togetthecorrectvalue,oneofthenumbersmustbeexplicitlyconvertedtoafloating-pointnumber.
floatf=3/(float)2;//1.5
AssignmentOperatorsThesecondgroupistheassignmentoperators.Mostimportantly,theassignmentoperator(=)itself,whichassignsavaluetoavariable.
CombinedAssignmentOperatorsAcommonuseoftheassignmentandarithmeticoperatorsistooperateonavariableandthentosavetheresultbackintothatsamevariable.Theseoperationscanbeshortenedwiththecombinedassignment
operators.
x+=5;//x=x+5;x-=5;//x=x-5;x*=5;//x=x*5;x/=5;//x=x/5;x%=5;//x=x%5;
IncrementandDecrementOperatorsAnothercommonoperationistoincrementordecrementavariablebyone.Thiscanbesimplifiedwiththeincrement(++)anddecrement(--)operators.
x++;//x=x+1;x--;//x=x-1;
Bothofthesecanbeusedeitherbeforeorafteravariable.
x++;//post-incrementx--;//post-decrement++x;//pre-increment--x;//pre-decrement
Theresultonthevariableisthesamewhicheverisused.Thedifferenceisthatthepost-operatorreturnstheoriginalvaluebeforeitchangesthevariable,whilethepre-operatorchangesthevariablefirstandthenreturnsthevalue.
intx,y;x=5;y=x++;//y=5,x=6x=5;y=++x;//y=6,x=6
ComparisonOperatorsThecomparisonoperatorscomparetwovaluesandreturneithertrueorfalse.Theyaremainlyusedtospecifyconditions,whichareexpressionsthatevaluatetoeithertrueorfalse.
boolb=(2==3);//false//equaltob=(2!=3);//true//notequaltob=(2>3);//false//greaterthanb=(2<3);//true//lessthanb=(2>=3);//false//greaterthanorequaltob=(2<=3);//true//lessthanorequalto
LogicalOperators
Thelogicaloperatorsareoftenusedtogetherwiththecomparisonoperators.Logicaland(&&)evaluatestotrueifboththeleftandrightsidesaretrue,andlogicalor(||)istrueifeithertheleftorrightsideistrue.ForinvertingaBooleanresultthereisthelogicalnot(!)operator.Notethatforboth“logicaland”and“logicalor”theright-handsidewillnotbeevaluatediftheresultisalreadydeterminedbytheleft-handside.
boolb=(true&&false);//false//logicalandb=(true||false);//true//logicalorb=!(true);//false//logicalnot
BitwiseOperatorsThebitwiseoperatorscanmanipulateindividualbitsinsideaninteger.Forexample,the“bitwiseor”operator(|)makestheresultingbit1ifthebitsaresetoneithersideoftheoperator.
intx=5&4;//101&100=100(4)//andx=5|4;//101|100=101(5)//orx=5^4;//101^100=001(1)//xorx=4<<1;//100<<1=1000(8)//leftshiftx=4>>1;//100>>1=10(2)//rightshiftx=~4;//~00000100=11111011(-5)//invert
Thebitwiseoperatorsalsohavecombinedassignmentoperators.
intx=5;x&=4;//101&100=100(4)//andx=5;x|=4;//101|100=101(5)//orx=5;x^=4;//101^100=001(1)//xorx=5;x<<=1;//101<<1=1010(10)//leftshiftx=5;x>>=1;//101>>1=10(2)//rightshift
OperatorPrecedenceInC++,expressionsarenormallyevaluatedfromlefttoright.However,whenanexpressioncontainsmultipleoperators,theprecedenceofthoseoperatorsdecidestheorderinwhichtheyareevaluated.Theorderofprecedencecanbeseeninthefollowingtable,wheretheoperatorwiththelowestprecedencewillbeevaluatedfirst.Thissamebasicorderalsoappliestomanyotherlanguages,suchasC,Java,andC#.
Togiveanexample,logicaland(&&)bindsweakerthanrelationaloperators,whichinturnbindweakerthanarithmeticoperators.
boolb=2+3>1*4&&5/5==1;//true
Tomakethingsclearer,parenthesescanbeusedtospecifywhichpartoftheexpressionwillbeevaluatedfirst.Asseeninthetable,parenthesesareamongtheoperatorswithlowestprecedence.
boolb=((2+3)>(1*4))&&((5/5)==1);//true
CHAPTER5
Pointers
Apointerisavariablethatcontainsthememoryaddressofanothervariable,calledthepointee.
CreatingPointersPointersaredeclaredasanyothervariable,exceptthatanasterisk(*)isplacedbetweenthedatatypeandthepointer’sname.Thedatatypeuseddetermineswhattypeofmemoryitwillpointto.
int*p;//pointertoanintegerint*q;//alternativesyntax
Apointercanpointtoavariableofthesametypebyprefixingthatvariablewithanampersand,inordertoretrieveitsaddressandassignittothepointer.Theampersandisknownastheaddress-ofoperator(&).
inti=10;p=&i;//addressofiassignedtop
DereferencingPointersThepointerabovenowcontainsthememoryaddresstotheintegervariable.Referencingthepointerwillretrievethisaddress.Toobtaintheactualvaluestoredinthataddressthepointermustbeprefixedwithanasterisk,knownasthedereferenceoperator(*).
std::cout<<"Addressofi:"<<p;//ex.0017FF1Cstd::cout<<"Valueofi:"<<*p;//10
Whenwritingtothepointer,thesamemethodisused.Withouttheasteriskthepointerisassignedanewmemoryaddress,andwiththeasterisktheactualvalueofthevariablepointedtowillbeupdated.
p=&i;//addressofiassignedtop*p=20;//valueofichangedthroughp
Ifasecondpointeriscreatedandassignedthevalueofthefirstpointeritwillthengetacopyofthe
firstpointer’smemoryaddress.
int*p2=p;//copyofp(copiesaddressstoredinp)
PointingtoaPointerSometimesitcanbeusefultohaveapointerthatcanpointtoanotherpointer.Thisisdonebydeclaringapointerwithtwoasterisksandthenassigningittheaddressofthepointerthatitwillreference.Thiswaywhentheaddressstoredinthefirstpointerchanges,thesecondpointercanfollowthatchange.
int**r=&p;//pointertop(assignsaddressofp)
Referencingthesecondpointernowgivestheaddressofthefirstpointer.Dereferencingthesecondpointergivestheaddressofthevariableanddereferencingitagaingivesthevalueofthevariable.
std::cout<<"Addressofp:"<<r;//ex.0017FF28std::cout<<"Addressofi:"<<*r;//ex.0017FF1Cstd::cout<<"Valueofi:"<<**r;//20
DynamicAllocationOneofthemainusagesofpointersistoallocatememoryduringrun-time–socalleddynamicallocation.Intheexamplessofar,theprogramshaveonlyhadasmuchmemoryavailableashasbeendeclaredforthevariablesatcompile-time.Thisisreferredtoasstaticallocation.Ifanyadditionalmemoryisneededatrun-time,thenewoperatorhastobeused.Thisoperatorallowsfordynamicallocationofmemory,whichcanonlybeaccessedthroughpointers.Thenewoperatortakeseitheraprimitivedatatypeoranobjectasitsargument,anditwillreturnapointertotheallocatedmemory.
int*d=newint;//dynamicallocation
Animportantthingtoknowaboutdynamicallocationisthattheallocatedmemorywillnotbereleasedliketherestoftheprogrammemorywhenitisnolongerrequired.Instead,ithastobemanuallyreleasedwiththedeletekeyword.Thisallowsyoutocontrolthelifetimeofadynamicallyallocatedobject,butitalsomeansthatyouareresponsiblefordeletingitonceitisnolongerneeded.Forgettingtodeletememorythathasbeenallocatedwiththenewkeywordwillgivetheprogrammemoryleaks,becausethatmemorywillstayallocateduntiltheprogramshutsdown.
deleted;//releaseallocatedmemory
NullPointerApointershouldbesettozerowhenitisnotassignedtoavalidaddress.Suchapointeriscalledanullpointer.Doingthiswillallowyoutocheckwhetherthepointercanbesafelydereferenced,becauseavalidpointerwillneverbezero.
Forexample,althoughthepreviouspointerhashaditsmemoryreleased,itsstoredaddressstillpointstoanowinaccessiblememorylocation.Tryingtodereferencesuchapointerwillcausearun-timeerror.Tohelppreventthis,thedeletedpointershouldbesettozero.Notethattryingtodeleteanalreadydeletednullpointerissafe.However,ifthepointerhasnotbeensettozero,attemptingtodeleteitagainwillcausememorycorruptionandpossiblycrashtheprogram.
deleted;d=0;//markasnullpointerdeleted;//safe
Sinceyoumaynotalwaysknowwhetherapointerisvalid,acheckshouldbemadewheneverapointerisdereferencedtomakesurethatitisnotzero.
if(d!=0){*d=10;}//checkfornullpointer
TheconstantNULLcanalsobeusedtosignifyanullpointer.NULListypicallydefinedaszeroinC++,makingthechoiceofwhichtouseamatterofpreference.Theconstantisdefinedinthestdio.hstandardlibraryfile,whichisincludedthroughiostream.
#include<iostream>//...if(d!=NULL){*d=10;}//checkfornullpointer
C++11introducedthekeywordnullptrtodistinguishbetween0andanullpointer.TheadvantageofusingnullptristhatunlikeNULL,itwillnotimplicitlyconverttoanintegertype.Theliteralhasitsowntype,nullptr_t,whichcanonlybeimplicitlyconvertedtopointerandbooltypes.
int*p=nullptr;//okinti=nullptr;//errorboolb=nullptr;//ok(false)
nullptr_tmynull=nullptr;//ok
CHAPTER6
References
Referencesallowaprogrammertocreateanewnameforavariable.Theyprovideasimpler,saferandlesspowerfulalternativetopointers.
CreatingReferencesAreferenceisdeclaredinthesamewayasaregularvariable,exceptthatanampersandisappendedbetweenthedatatypeandthevariablename.Furthermore,atthesametimeasthereferenceisdeclareditmustbeinitializedwithavariableofthespecifiedtype.
intx=5;int&r=x;//risanaliastoxint&s=x;//alternativesyntax
Oncethereferencehasbeenassigned,orseated,itcanneverbereseatedtoanothervariable.Thereferencehasineffectbecomeanaliasforthevariableandcanbeusedexactlyasthoughitwastheoriginalvariable.
r=10;//assignsvaluetor/x
ReferencesandPointersAreferenceissimilartoapointerthatalwayspointstothesamething.However,whileapointerisavariablethatpointstoanothervariable,areferenceisonlyanaliasanddoesnothaveanaddressofitsown.
int*ptr=&x;//ptrassignedaddresstox
ReferenceandPointerGuidelineGenerally,wheneverapointerdoesnotneedtobereassignedareferenceshouldbeusedinstead,becauseareferenceissaferthanapointersinceitmustalwaysrefertoavariable.Thismeansthatthereisnoneed
tocheckifareferencereferstonull,asshouldbedonewithpointers.Itispossibleforareferencetobeinvalid–forexamplewhenareferencereferstoanullpointer–butitismucheasiertoavoidthiskindofmistakewithreferencesthanitiswithpointers.
int*ptr=0;//nullpointerint&ref=*ptr;ref=10;//segmentationfault(invalidmemoryaccess)
RvalueReferenceWithC++11cameanewkindofreferencecalledanrvaluereference.Thisreferencecanbindandmodifytemporaryobjects(rvalues),suchasliteralvaluesandfunctionreturnvalues.Anrvaluereferenceisformedbyplacingtwoampersandsafterthetype.
int&&ref=1+2;//rvaluereference
Thervaluereferenceextendsthelifetimeofthetemporaryobjectandallowsittobeusedlikeanordinaryvariable.
ref+=3;cout<<ref;//"6"
Thebenefitofrvaluereferencesisthattheyallowunnecessarycopyingtobeavoidedwhendealingwithtemporaryobjects.Thisoffersgreaterperformance,particularlywhenhandlinglargertypes,suchasstringsandobjects.
CHAPTER7
Arrays
Anarrayisadatastructureusedforstoringacollectionofvaluesthatallhavethesamedatatype.
ArrayDeclarationandAllocationTodeclareanarrayyoustartasyouwouldanormalvariabledeclaration,butinadditionappendasetofsquarebracketsfollowingthearray’sname.Thebracketscontainthenumberofelementsinthearray.Thedefaultvaluesfortheseelementsarethesameasforvariables–elementsinglobalarraysareinitializedtotheirdefaultvaluesandelementsinlocalarraysremainuninitialized.
intmyArray[3];//integerarraywith3elements
ArrayAssignmentToassignvaluestotheelementsyoucanreferencethemoneatatimebyplacingtheelement’sindexinsidethesquarebrackets,startingwithzero.
myArray[0]=1;myArray[1]=2;myArray[2]=3;
Alternatively,youcanassignvaluesatthesametimeasthearrayisdeclaredbyenclosingthemincurlybrackets.Thespecifiedarraylengthmayoptionallybeleftouttoletthearraysizebedecidedbythenumberofvaluesassigned.
intmyArray[3]={1,2,3};intmyArray[]={1,2,3};
Oncethearrayelementsareinitializedtheycanbeaccessedbyreferencingtheindexoftheelementyouwant.
std::cout<<myArray[0];//1
Multi-dimensionalArraysArrayscanbemademulti-dimensionalbyaddingmoresetsofsquarebrackets.Aswithsingle-dimensionalarrays,theycaneitherbefilledinoneatatimeorallatonceduringthedeclaration.
intmyArray[2][2]={{0,1},{2,3}};myArray[0][0]=0;myArray[0][1]=1;
Theextracurlybracketsareoptional,butincludingthemisgoodpracticesinceitmakesthecodeeasiertounderstand.
intmArray[2][2]={0,1,2,3};//alternative
DynamicArraysBecausethearraysabovearemadeupofstatic(non-dynamic)memory,theirsizemustbedeterminedbeforeexecution.Therefore,thesizeneedstobeaconstantvalue.Inordertocreateanarraywithasizethatisnotknownuntilrun-timeyouneedtousedynamicmemory,whichisallocatedwiththenewkeywordandmustbeassignedtoapointerorreference.
int*p=newint[3];//dynamicallyallocatedarray
AnarrayinC++behavesasaconstantpointertothefirstelementinthearray.Thereferencingofarrayelementscanthereforebemadejustaswellwithpointerarithmetic.Byincrementingthepointerbyoneyoumovetothenextelementinthearray,becausechangestoapointer’saddressareimplicitlymultipliedbythesizeofthepointer’sdatatype.
*(p+1)=10;//p[1]=10;
ArraySizeJustaswithanyotherpointer,itispossibletoexceedthevalidrangeofanarrayandtherebyrewritesomeadjacentmemory.Thisshouldalwaysbeavoidedsinceitcanleadtounexpectedresultsorcrashtheprogram.
intmyArray[2]={1,2};myArray[2]=3;//outofboundserror
Todeterminethelengthofaregular(staticallyallocated)array,thesizeofoperatorcanbeused.
intlength=sizeof(myArray)/sizeof(int);//2
Thismethodcannotbeusedfordynamicallyallocatedarrays.Theonlywaytodeterminethesizeofsuchanarrayisthroughthevariableusedinitsallocation.
intsize=3;int*p=newint[size];//dynamicallyallocatedarray
Whenyouaredoneusingadynamicarrayyoumustremembertodeleteit.Thisisdoneusingthedeletekeywordwithanappendedsetofsquarebrackets.
delete[]p;//releaseallocatedarray
CHAPTER8
String
ThestringclassinC++isusedtostorestringvalues.Beforeastringcanbedeclaredthestringheadermustfirstbeincluded.Thestandardnamespacecanalsobeincludedsincethestringclassispartofthatnamespace.
#include<string>usingnamespacestd;
Stringscanthenbedeclaredlikeanyotherdatatype.Toassignastringvaluetoastringvariable,delimittheliteralsbydoublequotesandassignthemtothevariable.Theinitialvaluecanalsobeassignedthroughconstructorinitializationatthesametimeasthestringisdeclared.
stringh="Hello";stringw("World");
StringCombiningTheplussign,knownastheconcatenationoperator(+)inthiscontext,isusedtocombinetwostrings.Ithasanaccompanyingassignmentoperator(+=)toappendastring.
stringa=h+w;//HelloWorldh+=w;//HelloWorld
TheconcatenationoperatorwillworkaslongasoneofthestringsitoperatesonisaC++string.
stringb="Hello"+w;//ok
ItisnotabletoconcatenatetwoCstringsortwostringliterals.Todothis,oneofthevalueshastobeexplicitlycasttoastring.
char*c="World";//C-stylestringb=(string)c+c;//okb="Hello"+(string)"World";//ok
Stringliteralswillalsobeimplicitlycombinediftheplussignisleftout.
b="Hel""lo";//ok
EscapeCharactersAstringliteralcanbeextendedtomorethanonelinebyputtingabackslashsign(\)attheendofeachline.
strings="Hello\World";
Toaddanewlinetothestringitself,theescapecharacter“\n”isused.
s="Hello\nWorld";
Thisbackslashnotationisusedtowritespecialcharacters,suchastaborformfeedcharacters.
Additionally,anyoneofthe128ASCIIcharacterscanbeexpressedbywritingabackslashfollowedbytheASCIIcodeforthatcharacter,representedaseitheranoctalorhexadecimalnumber.
"\07F"//octalcharacter(0-07F)"\0x177"//hexadecimalcharacter(0-0x177)
AsofC++11,escapecharacterscanbeignoredbyaddinga“R”beforethestringalongwithasetofparentheseswithinthedoublequotes.Thisiscalledarawstringandcanbeused,forinstance,tomakefilepathsmorereadable.
stringescaped="c:\\Windows\\System32\\cmd.exe";stringraw=R"(c:\Windows\System32\cmd.exe)";
StringCompareThewaytocomparetwostringsissimplybyusingtheequaltooperator(==).Thiswillnotcomparethememoryaddressesofthestrings,asisthecaseofCstrings.
strings="Hello";boolb=(s=="Hello");//true
StringFunctionsThestringclasshasalotoffunctions.Amongthemostusefulonesarethelengthandsizefunctions,whichbothreturnthenumberofcharactersinthestring.Theirreturntypeissize_t,whichisanunsigneddatatypeusedtoholdthesizeofanobject.Thisissimplyanaliasforoneofthebuilt-indatatypes,butwhichoneitisdefinedasvariesbetweencompilers.Thealiasisdefinedinthecrtdefs.hstandardlibraryfile,whichisincludedthroughiostream.
size_ti=s.length();//5,lengthofstringi=s.size();//5,sameaslength()
Anotherusefulfunctionissubstr(substring),whichrequirestwoparameters.Thesecondparameteristhenumberofcharacterstoreturnstartingfromthepositionspecifiedinthefirstparameter.
s.substr(0,2);//"He"
Asinglecharactercanalsobeextractedorchangedbyusingthearraynotation.
charc=s[0];//'H'
StringEncodingsAstringenclosedwithindoublequotesproducesanarrayofthechartype,whichcanonlyhold256uniquesymbols.Tosupportlargercharactersetsthewidecharactertypewchar_tisprovided.Stringliteralsofthistypearecreatedbyprependingthestringwithacapital“L”.Theresultingarraycanbestoredusingthewstringclass.Thisclassworkslikethebasicstringclassbutusesthewchar_tcharactertypeinstead.
wstrings1=L"Hello";wchar_t*s2=L"Hello";
Fixed-sizecharactertypeswereintroducedinC++11,namelychar16_tandchar32_t.ThesetypesprovidedefiniterepresentationsoftheUTF-16andUTF-32encodingsrespectively.UTF-16stringliteralsareprefixedwith“u”andcanbestoredusingtheu16stringclass.Likewise,UTF-32stringliteralsareprefixedwith“U”andarestoredintheu32stringclass.Theprefix“u8”wasalsoaddedtorepresentaUTF-8encodedstringliteral.
strings3=u8"UTF-8string";u16strings4=u"UTF-16string";u32strings5=U"UTF-32string";
SpecificUnicodecharacterscanbeinsertedintoastringliteralusingtheescapecharacter“\u”followedbyahexadecimalnumberrepresentingthecharacter.
strings6=u8"Anasterisk:\u002A";
CHAPTER9
Conditionals
Conditionalstatementsareusedtoexecutedifferentcodeblocksbasedondifferentconditions.
IfStatementTheifstatementwillonlyexecuteiftheexpressioninsidetheparenthesesisevaluatedtotrue.InC++,thisdoesnothavetobeaBooleanexpression.Itcanbeanyexpressionthatevaluatestoanumber,inwhichcasezeroisfalseandallothernumbersaretrue.
if(x<1){cout<<x<<"<1";}
Totestforotherconditions,theifstatementcanbeextendedbyanynumberofelseifclauses.
elseif(x>1){cout<<x<<">1";}
Theifstatementcanhaveoneelseclauseattheend,whichwillexecuteifallpreviousconditionsarefalse.
else{cout<<x<<"==1";}
Asforthecurlybrackets,theycanbeleftoutifonlyasinglestatementneedstobeexecutedconditionally.However,itisconsideredgoodpracticetoalwaysincludethemsincetheyimprovereadability.
if(x<1)cout<<x<<"<1";elseif(x>1)cout<<x<<">1";elsecout<<x<<"==1";
SwitchStatementTheswitchstatementchecksforequalitybetweenanintegerandaseriesofcaselabels,andthenpassesexecutiontothematchingcase.Itmaycontainanynumberofcaseclausesanditcanendwithadefaultlabelforhandlingallothercases.
switch(x){case0:cout<<x<<"is0";break;case1:cout<<x<<"is1";break;default:cout<<x<<"isnot1or2";break;}
Notethatthestatementsaftereachcaselabelendwiththebreakkeywordtoskiptherestoftheswitch.Ifthebreakisleftout,executionwillfallthroughtothenextcase,whichcanbeusefulifseveralcasesneedtobeevaluatedinthesameway.
TernaryOperatorInadditiontotheifandswitchstatementsthereistheternaryoperator(?:)thatcanreplaceasingleif/elseclause.Thisoperatortakesthreeexpressions.Ifthefirstoneistruethenthesecondexpressionisevaluatedandreturned,andifitisfalse,thethirdoneisevaluatedandreturned.
x=(x<0.5)?0:1;//ternaryoperator(?:)
C++allowsexpressionstobeusedasstand-alonecodestatements.Becauseofthistheternaryoperatorcannotjustbeusedasanexpression,butalsoasastatement.
(x<0.5)?x=0:x=1;//alternativesyntax
Theprogrammingtermexpressionreferstocodethatevaluatestoavalue,whereasastatementisacodesegmentthatendswithasemicolonoraclosingcurlybracket.
CHAPTER10
Loops
TherearethreeloopingstructuresavailableinC++,allofwhichareusedtoexecuteaspecificcodeblockmultipletimes.Justaswiththeconditionalifstatement,thecurlybracketsfortheloopscanbeleftoutifthereisonlyonestatementinthecodeblock.
WhileLoopThewhilelooprunsthroughthecodeblockonlyifitsconditionistrue,andwillcontinueloopingforaslongastheconditionremainstrue.Bearinmindthattheconditionisonlycheckedatthestartofeachiteration(loop).
inti=0;while(i<10){cout<<i++;}//0-9
Do-whileLoopThedo-whileloopworksinthesamewayasthewhileloop,exceptthatitcheckstheconditionafterthecodeblock.Itwillthereforealwaysrunthroughthecodeblockatleastonce.Noticethatthisloopendswithasemicolon.
intj=0;do{cout<<j++;}while(j<10);//0-9
ForLoopTheforloopisusedtorunthroughacodeblockaspecificnumberoftimes.Itusesthreeparameters.Thefirstoneinitializesacounterandisalwaysexecutedoncebeforetheloop.Thesecondparameterholdstheconditionfortheloopandischeckedbeforeeachiteration.Thethirdparametercontainstheincrementofthecounterandisexecutedattheendofeachloop.
for(intk=0;k<10;k++){cout<<k;}//0-9
Theforloophasseveralvariations.Forstarters,thefirstandthirdparameterscanbesplitintoseveralstatementsbyusingthecommaoperator.
for(intk=0,m=0;k<10;k++,m--){cout<<k+m;//0x10}
Thereisalsotheoptionofleavingoutanyoneoftheparameters.
for(;;){cout<<"infiniteloop";}
C++11introducedarange-basedforloopsyntaxforiteratingthrougharraysandothercontainertypes.Ateachiterationthenextelementinthearrayisboundtothereferencevariable,andtheloopcontinuesuntilithasgonethroughtheentirearray.
inta[3]={1,2,3};for(int&i:a){cout<<i;//"123"}
BreakandContinueTherearetwojumpstatementsthatcanbeusedinsideloops:breakandcontinue.Thebreakkeywordendstheloopstructure,andcontinueskipstherestofthecurrentiterationandcontinuesatthebeginningofthenextiteration.
for(inti=0;i<10;i++){break;//endloopcontinue;//startnextiteration}
GotoStatementAthirdjumpstatementthatmaybeusefultoknowofisgoto,whichperformsanunconditionaljumptoaspecifiedlabel.Thisinstructionisgenerallyneverusedsinceittendstomaketheflowofexecutiondifficulttofollow.
gotomyLabel;//jumptolabelmyLabel://labeldeclaration
CHAPTER11
Functions
Functionsarereusablecodeblocksthatwillonlyexecutewhencalled.
DefiningFunctionsAfunctioncanbecreatedbytypingvoidfollowedbythefunction’sname,asetofparenthesesandacodeblock.Thevoidkeywordmeansthatthefunctionwillnotreturnavalue.Thenamingconventionforfunctionsisthesameasforvariables–adescriptivenamewitheachwordinitiallycapitalized,exceptforthefirstone.
voidmyFunction(){cout<<"HelloWorld";}
CallingFunctionsThefunctionabovewillsimplyprintoutatextmessagewhenitiscalled.Toinvokeitfromthemainfunctionthefunction’snameisspecifiedfollowedbyasetofparentheses.
intmain(){myFunction();//"HelloWorld"}
FunctionParametersTheparenthesesthatfollowthefunctionnameareusedtopassargumentstothefunction.Todothisthecorrespondingparametersmustfirstbeaddedtothefunctiondeclarationintheformofacommaseparatedlist.
voidmyFunction(stringa,stringb){cout<<a+""+b;}
Afunctioncanbedefinedtotakeanynumberofparameters,andtheycanhaveanydatatypes.Justensurethefunctioniscalledwiththesametypesandnumberofarguments.
myFunction("Hello","World");//"HelloWorld"
Tobeprecise,parametersappearinfunctiondefinitions,whileargumentsappearinfunctioncalls.However,thetwotermsaresometimesusedinterchangeably.
DefaultParameterValuesItispossibletospecifydefaultvaluesforparametersbyassigningthemavalueinsidetheparameterlist.
voidmyFunction(stringa,stringb="Earth"){cout<<a+""+b;}
Then,ifthatargumentisunspecifiedwhenthefunctioniscalledthedefaultvaluewillbeusedinstead.Forthistoworkitisimportantthattheparameterswithdefaultvaluesaretotherightofthosewithoutdefaultvalues.
myFunction("Hello");//"HelloEarth"
FunctionOverloadingAfunctioninC++canbedefinedmultipletimeswithdifferentarguments.Thisisapowerfulfeaturecalledfunctionoverloadingthatallowsafunctiontohandleavarietyofparameterswithouttheprogrammerusingthefunctionneedingtobeawareofit.
voidmyFunction(stringa,stringb){cout<<a+""+b;}voidmyFunction(stringa){cout<<a;}voidmyFunction(inta){cout<<a;}
ReturnStatementAfunctioncanreturnavalue.Thevoidkeywordisthenreplacedwiththedatatypethefunctionwillreturn,andthereturnkeywordisaddedtothefunction’sbodyfollowedbyanargumentofthespecifiedreturntype.
intgetSum(inta,intb){returna+b;}
Returnisajumpstatementthatcausesthefunctiontoexitandreturnthespecifiedvaluetotheplacewherethefunctionwascalled.Forexample,thefunctionabovecanbepassedasanargumenttotheoutputstreamsincethefunctionevaluatestoaninteger.
cout<<getSum(5,10);//15
Thereturnstatementcanalsobeusedinvoidfunctionstoexitbeforetheendblockisreached.
voiddummy(){return;}
Notethatalthoughthemainfunctionissettoreturnanintegertype,itdoesnothavetoexplicitlyreturnavalue.Thisisbecausethecompilerwillautomaticallyaddareturnzerostatementtotheendofthemainfunction.
intmain(){return0;}
ForwardDeclarationAnimportantthingtokeepinmindinC++isthatfunctionsmustbedeclaredbeforetheycanbecalled.Thisdoesnotmeanthatthefunctionhastobeimplementedbeforeitiscalled.Itonlymeansthatthefunction’sheaderneedstobespecifiedatthebeginningofthesourcefile,sothatthecompilerknowsthatthefunctionexists.Thiskindofforwarddeclarationisknownasaprototype.
voidmyFunction(inta);//prototypeintmain(){myFunction(0);}voidmyFunction(inta){}
Theparameternamesintheprototypedonotneedtobeincluded.Onlythedatatypesmustbespecified.
voidmyFunction(int);
PassbyValueInC++,variablesofbothprimitiveandobjectdatatypesarebydefaultpassedbyvalue.Thismeansthatonlyacopyofthevalueorobjectispassedtothefunction.Therefore,changingtheparameterinanywaywillnotaffecttheoriginal,andpassingalargeobjectwillbeveryslow.
#include<iostream>
#include<string>usingnamespacestd;
voidchange(inti){i=10;}voidchange(strings){s="HelloWorld";}
intmain(){intx=0;//valuetypechange(x);//valueispassedcout<<x;//0
stringy="";//referencetypechange(y);//objectcopyispassedcout<<y;//""}
PassbyReferenceAlternatively,toinsteadpassavariablebyreferenceyoujustneedtoaddanampersandbeforetheparameter’snameinthefunction’sdefinition.Whenargumentsarepassedbyreference,bothprimitiveandobjectdatatypescanbechangedorreplacedandthechangeswillaffecttheoriginal.
voidchange(int&i){i=10;}
intmain(){intx=0;//valuetypechange(x);//referenceispassedcout<<x;//10}
PassbyAddressAsanalternativetopassingbyreference,argumentsmayalsobepassedbyaddressusingpointers.Thispassingtechniqueservesthesamepurposeaspassingbyreference,butusespointersyntaxinstead.
voidchange(int*i){*i=10;}
intmain(){intx=0;//valuetypechange(&x);//addressispassedcout<<x;//10}
ReturnbyValue,ReferenceorAddressInadditiontopassingvariablesbyvalue,referenceoraddress,avariablemayalsobereturnedinoneoftheseways.Mostcommonly,afunctionreturnsbyvalue,inwhichcaseacopyofthevalueisreturnedtothecaller.
intbyVal(inti){returni+1;}
intmain(){inta=10;cout<<byVal(a);//11}
Toreturnbyreferenceinstead,anampersandisplacedafterthefunction’sreturntype.Thefunctionmustthenreturnavariableandmaynotreturnanexpressionorliteral,ascanbedonewhenusingreturnbyvalue.Thevariablereturnedshouldneverbealocalvariable,sincethememorytothesevariablesisreleasedwhenthefunctionends.Instead,returnbyreferenceiscommonlyusedtoreturnanargumentthathasalsobeenpassedtothefunctionbyreference.
int&byRef(int&i){returni;}
intmain(){inta=10;cout<<byRef(a);//10}
Toreturnbyaddressthedereferenceoperatorisappendedtothefunction’sreturntype.Thisreturntechniquehasthesametworestrictionsaswhenreturningbyreference–theaddressofavariablemustbereturnedandthatreturnedvariablemustnotbelocaltothefunction.
int*byAdr(int*i){returni;}
intmain(){inta=10;cout<<*byAdr(&a);//10}
InlineFunctionsAthingtokeepinmindwhenusingfunctionsisthateverytimeafunctioniscalled,aperformanceoverheadoccurs.Topotentiallyremovethisoverheadyoucanrecommendthatthecompilerinlinesthecallstoaspecificfunctionbyusingtheinlinefunctionmodifier.Thiskeywordisbestsuitedforsmallfunctionsthatarecalledinsideloops.Itshouldnotbeusedonlargerfunctionssinceinliningthesecan
severelyincreasethesizeofthecode,whichwillinsteaddecreaseperformance.
inlineintmyInc(inti){returni++;}
Notethattheinlinekeywordisonlyarecommendation.Thecompilermayinitsattemptstooptimizethecodechoosetoignorethisrecommendationanditmayalsoinlinefunctionsthatdonothavetheinlinemodifier.
AutoandDecltypeTwonewkeywordswereintroducedinC++11:autoanddecltype.Bothofthesekeywordsareusedfortypedeductionduringcompilation.Theautokeywordworksasaplaceholderforatypeandinstructsthecompilertoautomaticallydeducethetypeofthevariablebasedonitsinitializer.
autoi=5;//intautod=3.14;//doubleautob=false;//bool
Autotranslatestothecoretypeoftheinitializer,whichmeansthatanyreferenceandconstantspecifiersaredropped.
int&iRef=i;automyAuto=iRef;//int
Droppedspecifierscanbemanuallyreappliedasneeded.Theampersandherecreatesaregular(lvalue)reference.
auto&myRef=iRef;//int&
Alternatively,twoampersandscanbeused.Thisnormallydesignatesanrvaluereference,butinthecaseofautoitmakesthecompilerautomaticallydeduceeitheranrvalueoranlvaluereference,basedonthegiveninitializer.
inti=1;auto&&a=i;//int&(lvaluereference)auto&&b=2;//int&&(rvaluereference)
Theautospecifiermaybeusedanywhereavariableisdeclaredandinitialized.Forinstance,thetypeoftheforloopiteratorbelowissettoauto,sincethecompilercaneasilydeducethetype.
#include<vector>usingnamespacestd;//...vector<int>myVector{1,2,3};for(auto&x:myVector){cout<<x;}//"123"
PriortoC++11therewasnorange-basedforlooporautospecifier.Iteratingoveravectorthenrequiredamoreverbosesyntax.
for(vector<int>::size_typei=0;i!=myVector.size();i++){cout<<myVector[i];//"123"}
Thedecltypespecifierworkssimilartoauto,exceptitdeducestheexactdeclaredtypeofagivenexpression,includingreferences.Thisexpressionisspecifiedinparentheses.
decltype(3)b=3;//int&&
InC++14,automaybeusedastheexpressionfordecltype.Thekeywordautoisthenreplacedwiththeinitializingexpression,allowingtheexacttypeoftheinitializertobededuced.
decltype(auto)=3;//int&&
Usingautoisoftenthesimplerchoicewhenaninitializerisavailable.Decltypeismainlyusedtoforwardfunctionreturntypes,withouthavingtoconsiderwhetheritisareferenceorvaluetype.
decltype(5)getFive(){return5;}//int
C++11addedatrailingreturntypesyntax,whichallowsafunction’sreturnvaluetobespecifiedaftertheparameterlist,followingthearrowoperator(->).Thisenablestheparametertobeusedwhendeducingthereturntypewithdecltype.TheuseofautointhiscontextinC++11justmeansthattrailingreturntypesyntaxisbeingused.
autogetValue(intx)->decltype(x){returnx;}//int
TheabilitytouseautoforreturntypedeductionwasaddedinC++14.Thisenabledthecorereturntypetobededuceddirectlyfromthereturnstatement,
autogetValue(intx){returnx;}//int
Moreover,autocanbeusedtogetherwithdecltypetodeducetheexacttypefollowingtherulesofdecltype.
decltype(auto)getRef(int&x){returnx;}//int&
Themainusefortypedeductionistoreducetheverbosityofthecodeandimprovereadability,particularlywhendeclaringcomplicatedtypeswherethetypeiseitherdifficulttoknowordifficulttowrite.KeepinmindthatinmodernIDEsyoucanhoveroveravariabletocheckitstype,evenifthetypehasbeenautomaticallydeduced.
LambdaFunctionsC++11addstheabilitytocreatelambdafunctions,whichareunnamedfunctionobjects.Thisprovidesacompactwaytodefinefunctionsattheirpointofuse,withouthavingtocreateanamedfunctionsomewhereelse.Thefollowingexamplecreatesalambdathatacceptstwointargumentsandreturnstheirsum.
autosum=[](intx,inty)->int
{returnx+y;};
cout<<sum(2,3);//"5"
Includingthereturntypeisoptionalifthecompilercandeducethereturnvaluefromthelambda.InC++11thisrequiredthelambdatocontainjustasinglereturnstatement,whereasC++14extendedreturntypedeductiontoanylambdafunction.Notethatthearrowoperator(->)isalsoomittedwhenleavingoutthereturntype.
autosum=[](intx,inty){returnx+y;};
C++11requireslambdaparameterstobedeclaredwithconcretetypes.ThisrequirementwasrelaxedinC++14,allowinglambdastouseautotypededuction.
autosum=[](autox,autoy){returnx+y;};
Lambdasaretypicallyusedforspecifyingsimplefunctionsthatareonlyreferencedonce,oftenbypassingthefunctionobjectasanargumenttoanotherfunction.Thiscanbedoneusingafunctionwrapperwithamatchingparameterlistandreturntype,asinthefollowingexample.
#include<iostream>#include<functional>usingnamespacestd;
voidcall(intarg,function<void(int)>func){func(arg);}
intmain(){autoprintSquare=[](intx){cout<<x*x;};call(2,printSquare);//"4"}
Alllambdasstartwithasetofsquarebrackets,calledthecaptureclause.Thisclausespecifiesvariablesfromthesurroundingscopethatcanbeusedwithinthelambdabody.Thiseffectivelypassesadditionalargumentstothelambda,withouttheneedtospecifytheseintheparameterlistofthefunctionwrapper.Thepreviousexamplecanthereforeberewritteninthefollowingway.
voidcall(function<void()>func){func();}
intmain(){inti=2;autoprintSquare=[i](){cout<<i*i;};call(printSquare);//"4"}
Thevariableisherecapturedbyvalueandsoacopyisusedwithinthelambda.Variablescanalsobecapturedbyreferenceusingthefamiliarampersandprefix.Notethatthelambdaisheredefinedandcalled
inthesamestatement.
inta=1;[&a](intx){a+=x;}(2);cout<<a;//"3"
Itispossibletospecifyadefaultcapturemode,toindicatehowanyunspecifiedvariableusedinsidethelambdaistobecaptured.A[=]meansthevariablesarecapturedbyvalueand[&]capturesthembyreference.Variablescapturedbyvaluearenormallyconstant,butthemutablespecifiercanbeusedtoallowsuchvariablestobemodified.
inta=1,b=1;[&,b]()mutable{b++;a+=b;}();cout<<a<<b;//"31"
AsofC++14,variablesmayalsobeinitializedinsidethecaptureclause.Ifthereisnovariablewiththesamenameintheouterscope,thevariable’stypewillbededucedasifbyauto.
inta=1;[&,b=2](){a+=b;}();cout<<a;//"3"
CHAPTER12
Class
Aclassisatemplateusedtocreateobjects.Todefineonetheclasskeywordisusedfollowedbyaname,acodeblockandasemicolon.Thenamingconventionforclassesismixedcase,meaningthateachwordshouldbeinitiallycapitalized.
classMyRectangle{};
Classmemberscanbedeclaredinsidetheclass;thetwomainkindsarefieldsandmethods.Fieldsarevariablesandtheyholdthestateoftheobject.Methodsarefunctionsandtheydefinewhattheobjectcando.
classMyRectangle{intx,y;};
ClassMethodsAmethodbelongingtoaclassisnormallydeclaredasaprototypeinsideoftheclass,andtheactualimplementationisplacedaftertheclass’sdefinition.Themethod’snameoutsidetheclassthenneedstobeprefixedwiththeclassnameandthescoperesolutionoperatorinordertodesignatetowhichclassthemethoddefinitionbelongs.
classMyRectangle{intx,y;intgetArea();};
intMyRectangle::getArea(){returnx*y;}
InlineMethods
Ifthemethodisshortandyouwanttorecommendtothecompilerthatthefunction’scodeshouldbeinserted(inlined)intothecaller’scode,onewaytodothiswouldbetousetheinlinekeywordinthemethod’sdefinition.
inlineintMyRectangle::getArea(){returnx*y;}
Amoreconvenientwayistosimplydefinethemethodinsideoftheclass.Thiswillimplicitlyrecommendtothecompilerthatthemethodshouldbeinlined.
classMyRectangle{intx,y;intgetArea(){returnx*y;}};
ObjectCreationTheclassdefinitionisnowcomplete.Inordertouseityoufirsthavetocreateanobjectoftheclass,alsocalledaninstance.Thiscanbedoneinthesamewayasvariablesaredeclared.
intmain(){MyRectangler;//objectcreation}
AccessingObjectMembersBeforethemembersthatthisobjectcontainscanbeaccessed,theyfirstneedtobedeclaredaspublicintheclassdefinition,byusingthepublickeywordfollowedbyacolon.
classMyRectangle{public:intx,y;intgetArea(){returnx*y;}};
Themembersofthisobjectcannowbereachedusingthedotoperator(.)aftertheinstancename.
r.x=10;r.y=5;intz=r.getArea();//50(5*10)
Anynumberofobjectscanbecreatedbasedonaclass,andeachoneofthemwillhaveitsownsetoffieldsandmethods.
MyRectangler2;//anotherinstanceofMyRectangler2.x=25;//notsameasr.x
Whenusinganobjectpointer,thearrowoperator(->)allowsaccesstotheobject’smembers.Thisoperatorbehaveslikethedotoperator,exceptthatitdereferencesthepointerfirst.Itisusedexclusivelywithpointerstoobjects.
MyRectangler;MyRectangle*p=&r;//objectpointer
p->getArea();(*p).getArea();//alternativesyntax
ForwardDeclarationClasses,justlikefunctions,mustbedeclaredbeforetheycanbereferenced.Ifaclassdefinitiondoesnotappearbeforethefirstreferencetothatclass,aclassprototypecanbespecifiedabovethereferenceinstead.
classMyClass;//classprototype
Thisforwarddeclarationallowstheclasstobereferencedinanycontextthatdoesnotrequiretheclasstobefullydefined.
classMyClass;//classprototypeMyClass*p;//allowedMyClassf(MyClass&);//allowed
MyClasso;//error,definitionrequiredsizeof(MyClass);//error,definitionrequired
Notethatevenwithaprototype,youstillcannotcreateanobjectofaclassbeforeithasbeendefined.
CHAPTER13
Constructor
Inadditiontofieldsandmethods,aclasscancontainaconstructor.Thisisaspecialkindofmethodusedtoconstruct,orinstantiate,theobject.Italwayshasthesamenameastheclassanddoesnothaveareturntype.Tobeaccessiblefromanotherclasstheconstructorneedstobedeclaredinasectionmarkedwiththepublicaccessmodifier.
classMyRectangle{public:intx,y;MyRectangle();};
MyRectangle::MyRectangle(){x=10;y=5;}
Whenanewinstanceofthisclassiscreatedtheconstructormethodwillbecalled,whichinthiscaseassignsdefaultvaluestothefields.
intmain(){MyRectangles;}
ConstructorOverloadingAswithanyothermethodtheconstructorcanbeoverloaded.Thiswillallowanobjecttobecreatedwithdifferentargumentlists.
classMyRectangle{public:intx,y;MyRectangle();MyRectangle(int,int);};
MyRectangle::MyRectangle(){x=10;y=5;}MyRectangle::MyRectangle(inta,intb){x=a;y=b;}
Forexample,withthetwoconstructorsdefinedabovetheobjectcanbeinitializedeitherwithnoargumentsorwithtwoarguments,whichwillbeusedtoassignthefields.
//CallsparameterlessconstructorMyRectangler;
//CallsconstructoracceptingtwointegersMyRectanglet(2,3);
C++11addedtheabilityforconstructorstocallotherconstructors.Usingthisfeaturetheparameterlessconstructorcreatedearlierishereredefinedtocallthesecondconstructor.
MyRectangle::MyRectangle():MyRectangle(10,5);
ThiskeywordInsidetheconstructor,aswellasinothermethodsbelongingtotheobject–socalledinstancemethods–aspecialkeywordcalledthiscanbeused.Thisisapointertothecurrentinstanceoftheclass.Itcanbeusefulif,forexample,theconstructor’sparameternamesarethesameasthefieldnames.Thefieldscanthenstillbeaccessedbyusingthethispointer,eventhoughtheyareovershadowedbytheparameters.
MyRectangle::MyRectangle(intx,inty){this->x=x;this->y=y;}
FieldInitializationAsanalternativetoassigningfieldsinsidetheconstructor,theymayalsobeassignedbyusingtheconstructorinitializationlist.Thisliststartswithacolonaftertheconstructorparameters,followedbycallstothefield’sownconstructors.Thisisactuallytherecommendedwayofassigningfieldsthroughaconstructor,becauseitgivesbetterperformancethanassigningthefieldsinsidetheconstructor.
MyRectangle::MyRectangle(inta,intb):x(a),y(b){}
Fieldscanalsobeassignedaninitialvalueintheirclassdefinition,aconvenientfeaturethatwasaddedinC++11.Thisvalueisautomaticallyassignedwhenanewinstanceiscreated,beforetheconstructorisrun.Assuch,thisassignmentcanbeusedtospecifyadefaultvalueforafieldthatmaybeoverriddenintheconstructor.
classMyRectangle{public://Classmemberinitializationintx=10;inty=5;
};
DefaultConstructorIfnoconstructorsaredefinedforaclassthecompilerwillautomaticallycreateadefaultparameterlessconstructorwhentheprogramcompiles.Becauseofthis,aclasscanbeinstantiatedevenifnoconstructorhasbeenimplemented.Thedefaultconstructorwillonlyallocatememoryfortheobject.Itwillnotinitializethefields.Incontrasttoglobalvariables,fieldsinC++arenotautomaticallyinitializedtotheirdefaultvalues.Thefieldswillcontainwhatevergarbageisleftintheirmemorylocationsuntiltheyareexplicitlyassignedvalues.
DestructorInadditiontoconstructors,aclasscanalsohaveanexplicitlydefineddestructor.Thedestructorisusedtoreleaseanyresourcesallocatedbytheobject.Itiscalledautomaticallybeforeanobjectisdestroyed,eitherwhentheobjectpassesoutofscopeorwhenitisexplicitlydeletedforobjectscreatedwiththenewoperator.Thenameofthedestructoristhesameastheclassname,butprecededbyatilde(~).Aclassmayonlyhaveonedestructoranditnevertakesanyargumentsorreturnsanything.
classSemaphore{public:bool*sem;
Semaphore(){sem=newbool;}~Semaphore(){deletesem;}};
SpecialMemberFunctionsThedefaultconstructorandthedestructorarebothspecialmemberfunctionsthatthecompilerwillautomaticallyprovideforanyclassthatdonotexplicitlydefinethem.Twomoresuchmethodsarethecopyconstructorandthecopyassignmentoperator(operator=).WiththeC++11standardcamewaysofcontrollingwhethertoallowthesespecialmemberfunctionsornotthroughthedeleteanddefaultspecifiers.Thedeletespecifierforbidsthecallingofafunction,whilethedefaultspecifierexplicitlystatesthatthecompiler-generateddefaultwillbeused.
classA{public://ExplicitlyincludedefaultconstructorA()=default;
A(inti);
//DisablecopyconstructorA(constA&)=delete;
//DisablecopyassignmentoperatorA&operator=(constA&)=delete;};
ObjectInitializationC++providesanumberofdifferentwaystocreateobjectsandinitializetheirfields.Thefollowingclasswillbeusedtoillustratethesemethods.
classMyClass{public:inti;MyClass()=default;MyClass(intx):i(x){}};
DirectInitializationTheobjectcreationsyntaxthathasbeenusedsofariscalleddirectinitialization.Thissyntaxcanincludeasetofparentheseswhichareusedtopassargumentstoaconstructorintheclass.Iftheparameterlessconstructorisused,theparenthesesareleftout.
//DirectinitializationMyClassa(5);MyClassb;
ValueInitializationAnobjectcanalsobevalueinitialized.Theobjectisthencreatedbyusingtheclassnamefollowedbyasetofparentheses.Theparenthesescansupplyconstructorarguments,orremainemptytoconstructtheobjectusingtheparameterlessconstructor.Avalueinitializationcreatesonlyatemporaryobject,whichisdestroyedattheendofthestatement.Topreservetheobjectitmusteitherbecopiedtoanotherobjectorassignedtoareference.Assigningthetemporaryobjecttoareferencewillmaintaintheobjectuntilthatreferencegoesoutofscope.
//ValueinitializationconstMyClass&a=MyClass();MyClass&&b=MyClass();
Avalueinitializedobjectisalmostidenticaltoonecreatedbyusingdefaultinitialization.Aminordifferenceisthatnon-staticfieldswillinsomecasesbeinitializedtotheirdefaultvalueswhenusingvalueinitialization.
CopyInitializationIfanexistingobjectisassignedtoanobjectofthesametypewhenitisdeclared,thenewobjectwillbecopyinitialized.Thismeansthateachmemberoftheexistingobjectwillbecopiedtothenewobject.
//CopyinitializationMyClassa=MyClass();MyClassb(a);MyClassc=b;
Thisworksbecauseoftheimplicitcopyconstructorthatthecompilerprovides,whichiscalledforthesekindsofassignments.Thecopyconstructortakesasingleargumentofitsowntype,andthenconstructsacopyofthespecifiedobject.Notethatthisbehaviorisdifferentfrommanyotherlanguages,suchasJavaandC#.Inthoselanguagesinitializinganobjectwithanotherobjectwillonlycopytheobject’sreference,andnotcreateanewobjectcopy.
NewInitializationAnobjectcanbeinitializedthroughdynamicmemoryallocationbyusingthenewkeyword.Dynamicallyallocatedmemorymustbeusedthroughapointerorreference.Thenewoperatorreturnsapointer,sotoassignittoareferenceitneedstobedereferencedfirst.Keepinmindthatdynamicallyallocatedmemorymustbeexplicitlyfreedonceitisnolongerneeded.
//NewinitializationMyClass*a=newMyClass();MyClass&b=*newMyClass();//...deletea,b;
AggregateInitializationThereisasyntacticalshortcutavailablewheninitializinganobjectcalledaggregateinitialization.Thissyntaxallowsfieldstobesetbyusingabrace-enclosedlistofinitializers,inthesamewayascanbedonewitharrays.Aggregateinitializationcanonlybeusedwhentheclasstypedoesnotincludeanyconstructors,virtualfunctionsorbaseclasses.Thefieldsmustalsobepublic,unlesstheyaredeclaredasstatic.Eachfieldwillbesetintheordertheyappearintheclass.
//AggregateinitializationMyClassa={2};//iis2
UniformInitializationTheuniforminitializationwasintroducedinC++11toprovideaconsistentwaytoinitializetypesthatworksthesameforanytype.Thissyntaxlooksthesameasaggregateinitialization,withouttheuseoftheequalsign.
//UniforminitializationMyClassa{3};//iis3
Thisinitializationsyntaxworksnotjustforclassesbutforanytype,includingprimitives,strings,arrays,andstandardlibrarycontainerssuchasvector.
#include<string>#include<vector>usingnamespacestd;
inti{1};strings{"Hello"};inta[]{1,2};int*p=newint[2]{1,2};vector<string>box{"one","two"};
Uniforminitializationcanbeusedtocallaconstructor.Thisisdoneautomaticallybypassingalongtheproperargumentsforthatconstructor.
//CallparameterlessconstructorMyClassb{};
//CallcopyconstructorMyClassc{b};
Aclasscandefineaninitializer-list-constructor.Thisconstructoriscalledduringuniforminitializationandtakespriorityoverotherformsofconstruction,providedthatthetypespecifiedfortheinitializer_listtemplatematchesthetypeofthebrace-enclosedlistofarguments.Theargumentlistcanbeanylengthbutallelementsmustbeofthesametype.Inthefollowingexamplethetypeofthelistisintandsotheintegerlistusedtoconstructthisobjectispassedtotheconstructor.Theseintegersarethendisplayedusingarange-basedforloop.
#include<iostream>usingnamespacestd;
classNewClass{public:NewClass(initializer_list<int>args){for(autox:args)cout<<x<<"";}
CHAPTER14
Inheritance
Inheritanceallowsaclasstoacquirethemembersofanotherclass.Intheexamplebelow,SquareinheritsfromRectangle.Thisisspecifiedaftertheclassnamebyusingacolonfollowedbythepublickeyword,andthenameoftheclasstoinheritfrom.RectanglethenbecomesabaseclassofSquare,whichinturnbecomesaderivedclassofRectangle.Inadditiontoitsownmembers,SquaregainsallaccessiblemembersinRectangle,exceptforitsconstructorsanddestructor.
classRectangle{public:intx,y;intgetArea(){returnx*y;}};
classSquare:publicRectangle{};
UpcastingAnobjectcanbeupcasttoitsbaseclass,becauseitcontainseverythingthatthebaseclasscontains.Anupcastisperformedbyassigningtheobjecttoeitherareferenceorapointerofitsbaseclasstype.Intheexamplebelow,aSquareobjectisupcasttoRectangle.WhenusingRectangle’sinterfacetheSquareobjectwillbeviewedasaRectangle,soonlyRectangle’smemberscanbeaccessed.
Squares;Rectangle&r=s;//referenceupcastRectangle*p=&s;//pointerupcast
Aderivedclasscanbeusedanywhereabaseclassisexpected.Forexample,aSquareobjectcanbepassedasanargumenttoafunctionthatexpectsaRectangleobject.Thederivedobjectwillthenimplicitlybeupcasttoitsbasetype.
voidsetXY(Rectangle&r){r.x=2;r.y=3;}
intmain(){
Squares;setXY(s);}
DowncastingARectanglereferencethatpointstoaSquareobjectcanbedowncastbacktoaSquareobject.ThisdowncasthastobemadeexplicitsincedowncastinganactualRectangletoaSquareisnotallowed.
Square&a=(Square&)r;//referencedowncastSquare&b=(Square&)*p;//pointerdowncast
ConstructorInheritanceTomakesurethefieldsinthebaseclassareproperlyinitialized,theparameterlessconstructorofthebaseclassisautomaticallycalledwhenanobjectofthederivedclassiscreated.
classB1{public:intx;B1():x(5){}};
classD1:publicB1{};
intmain(){//CallsparameterlessconstructorsofD1andB1D1d;cout<<d.x;//"5"}
Thiscalltothebaseconstructorcanbemadeexplicitlyfromthederivedconstructor,byplacingitintheconstructor’sinitializationlist.Thisallowsargumentstobepassedalongtothebaseconstructor.
classB2{public:intx;B2(inta):x(a){}};
classD2:publicB2{
public:D2(inti):B2(i){}//callbaseconstructor};
Analternativesolutioninthiscaseistoinherittheconstructor.AsofC++11,thiscanbedonethroughausingstatement.
classD2:publicB2{public:usingB2::B2;//inheritallconstructorsinty{0};};
Notethatthebaseclassconstructorcannotinitializefieldsdefinedinthederivedclass.Therefore,anyfieldsdeclaredinthederivedclassshouldinitializethemselves.Thisisdonehereusingtheuniformnotation.
MultipleInheritanceC++allowsaderivedclasstoinheritfrommorethanonebaseclass.Thisiscalledmultipleinheritance.Thebaseclassesarespecifiedinacomma-separatedlist.
classPerson{}classEmployee{}
classTeacher:publicPerson,publicEmployee{}
Multipleinheritanceisnotcommonlyusedsincemostreal-worldrelationshipscanbebetterdescribedbysingleinheritance.Italsotendstosignificantlyincreasethecomplexityofthecode.
CHAPTER15
Overriding
Anewmethodinaderivedclasscanredefineamethodinabaseclassinordertogiveitanewimplementation.
HidingDerivedMembersIntheexamplebelow,Rectangle’sgetAreamethodisredeclaredinTrianglewiththesamesignature.Thesignatureincludesthename,parameterlistandreturntypeofthemethod.
classRectangle{public:intx,y;intgetArea(){returnx*y;}};
classTriangle:publicRectangle{public:Triangle(inta,intb){x=a;y=b;}intgetArea(){returnx*y/2;}};
IfaTriangleobjectiscreatedandthegetAreamethodisinvoked,thenTriangle’sversionofthemethodwillgetcalled.
Trianglet=Triangle(2,3);t.getArea();//3(2*3/2)callsTriangle’sversion
However,iftheTriangleisupcasttoaRectanglethenRectangle’sversionwillgetcalledinstead.
Rectangle&r=t;r.getArea();//6(2*3)callsRectangle’sversion
Thatisbecausetheredefinedmethodhasonlyhiddentheinheritedmethod.ThismeansthatTriangle’simplementationisredefineddownwardsintheclasshierarchytoanychildclassesofTriangle,butnot
upwardstothebaseclass.
OverridingDerivedMembersInordertoredefineamethodupwardsintheclasshierarchy–whatiscalledoverriding–themethodneedstobedeclaredwiththevirtualmodifierinthebaseclass.Thismodifierallowsthemethodtobeoverriddeninderivedclasses.
classRectangle{public:intx,y;virtualintgetArea(){returnx*y;}};
CallingthegetAreamethodfromRectangle’sinterfacewillnowinvokeTriangle’simplementation.
Rectangle&r=t;r.getArea();//3(2*3/2)callsTriangle’sversion
C++11addedtheoverridespecifier,whichindicatesthatamethodisintendedtoreplaceaninheritedmethod.Usingthisspecifierallowsthecompilertocheckthatthereisavirtualmethodwiththatsamesignature.Thispreventsthepossibilityofaccidentallycreatinganewvirtualmethod.
virtualfloatgetArea()override{}//error-nobaseclassmethodtooverride
AnotherspecifierintroducedinC++11isfinal.Thisspecifierpreventsavirtualmethodfrombeingoverriddeninderivedclasses.Italsopreventsderivedclassesfromusingthatsamemethodsignature.
classBase{virtualvoidfoo()final{}}
classDerived{voidfoo(){}//error:Base::foomarkedasfinal}
Thefinalspecifiercanalsobeappliedtoaclasstopreventanyclassfrominheritingit.
classBfinal{}classD:B{}//error:Bmarkedasfinal
BaseClassScoping
Itisstillpossibletoaccessaredefinedmethodfromaderivedclassbytypingtheclassnamefollowedbythescoperesolutionoperator.Thisiscalledbaseclassscopingandcanbeusedtoallowaccesstoredefinedmethodsthatareanynumberoflevelsdeepintheclasshierarchy.
classTriangle:publicRectangle{public:Triangle(inta,intb){x=a;y=b;}intgetArea(){returnRectangle::getArea()/2;}};
CHAPTER16
AccessLevels
Everyclassmemberhasanaccessibilitylevelthatdetermineswherethememberwillbevisible.TherearethreeofthemavailableinC++:public,protectedandprivate.Thedefaultaccesslevelforclassmembersisprivate.Tochangetheaccesslevelforasectionofcode,anaccessmodifierisusedfollowedbyacolon.Everyfieldormethodthatcomesafterthislabelwillhavethespecifiedaccesslevel,untilanotheraccesslevelissetortheclassdeclarationends.
classMyClass{intmyPrivate;public:intmyPublic;voidpublicMethod();};
PrivateAccessAllmembersregardlessoftheiraccesslevelareaccessibleintheclassinwhichtheyaredeclared,theenclosingclass.Thisistheonlyplacewhereprivatememberscanbeaccessed.
classMyClass{//Unrestrictedaccesspublic:intmyPublic;
//Definingorderivedclassonlyprotected:intmyProtected;
//Definingclassonlyprivate:intmyPrivate;voidtest(){myPublic=0;//allowedmyProtected=0;//allowedmyPrivate=0;//allowed
}};
ProtectedAccessAprotectedmembercanalsobeaccessedfrominsideaderivedclass,butitcannotbereachedfromanunrelatedclass.
classMyChild:publicMyClass{voidtest(){myPublic=0;//allowedmyProtected=0;//allowedmyPrivate=0;//inaccessible}};
PublicAccessPublicaccessgivesunrestrictedaccessfromanywhereinthecode.
classOtherClass{voidtest(MyClass&c){c.myPublic=0;//allowedc.myProtected=0;//inaccessiblec.myPrivate=0;//inaccessible}};
AccessLevelGuidelineAsaguideline,whenchoosinganaccesslevelitisgenerallybesttousethemostrestrictivelevelpossible.Thisisbecausethemoreplacesamembercanbeaccessed,themoreplacesitcanbeaccessedincorrectly,whichmakesthecodehardertodebug.Usingrestrictiveaccesslevelswillalsomakeiteasiertomodifytheclasswithoutbreakingthecodeforanyotherprogrammersusingthatclass.
FriendClassesandFunctions
Aclasscanbeallowedtoaccesstheprivateandprotectedmembersofanotherclassbydeclaringtheclassafriend.Thisisdonebyusingthefriendmodifier.Thefriendisallowedtoaccessallmembersintheclasswherethefriendisdefined,butnottheotherwayaround.
classMyClass{intmyPrivate;
//GiveOtherClassaccessfriendclassOtherClass;};
classOtherClass{voidtest(MyClassc){c.myPrivate=0;}//allowed};
Aglobalfunctioncanalsobedeclaredasafriendtoaclassinordertogainthesamelevelofaccess.
classMyClass{intmyPrivate;
//GivemyFriendaccessfriendvoidmyFriend(MyClassc);};
voidmyFriend(MyClassc){c.myPrivate=0;}//allowed
Public,ProtectedandPrivateInheritanceWhenaclassisinheritedinC++itispossibletochangetheaccessleveloftheinheritedmembers.Publicinheritanceallowsallmemberstokeeptheiroriginalaccesslevel.Protectedinheritancereducestheaccessofpublicmemberstoprotected.Privateinheritancerestrictsallinheritedmemberstoprivateaccess.
classMyChild:privateMyClass{//myPublicisprivate//myProtectedisprivate//myPrivateisprivate};
Privateisthedefaultinheritancelevel,althoughpublicinheritanceistheonethatisnearlyalwaysused.
CHAPTER17
Static
Thestatickeywordisusedtocreateclassmembersthatexistinonlyonecopy,whichbelongstotheclassitself.Thesemembersaresharedamongallinstancesoftheclass.Thisisdifferentfrominstance(non-static)members,whicharecreatedasnewcopiesforeachnewobject.
StaticFieldsAstaticfield(classfield)cannotbeinitializedinsidetheclasslikeaninstancefield.Insteaditmustbedefinedoutsideoftheclassdeclaration.Thisinitializationwillonlytakeplaceonce,andthestaticfieldwillthenremaininitializedthroughoutthelifeoftheapplication.
classMyCircle{public:doubler;//instancefield(oneperobject)staticdoublepi;//staticfield(onlyonecopy)};
doubleMyCircle::pi=3.14;
Toaccessastaticmemberfromoutsidetheclass,thenameoftheclassisusedfollowedbythescoperesolutionoperatorandthestaticmember.Thismeansthatthereisnoneedtocreateaninstanceofaclassinordertoaccessitsstaticmembers.
intmain(){doublep=MyCircle::pi;}
StaticMethodsInadditiontofields,methodscanalsobedeclaredasstatic,inwhichcasetheycanalsobecalledwithouthavingtodefineaninstanceoftheclass.However,becauseastaticmethodisnotpartofany
instanceitcannotuseinstancemembers.Methodsshouldthereforeonlybedeclaredstaticiftheyperformagenericfunctionthatisindependentofanyinstancevariables.Instancemethodsontheotherhand,incontrasttostaticmethods,canusebothstaticandinstancemembers.
classMyCircle{public:doubler;//instancevariable(oneperobject)staticdoublepi;//staticvariable(onlyonecopy)
doublegetArea(){returnpi*r*r;}staticdoublenewArea(doublea){returnpi*a*a;}};
intmain(){doublea=MyCircle::newArea(1);}
StaticLocalVariablesLocalvariablesinsideafunctioncanbedeclaredasstatictomakethefunctionrememberthevariable.Astaticlocalvariableisonlyinitializedoncewhenexecutionfirstreachesthedeclaration,andthatdeclarationisthenignoredeverysubsequenttimetheexecutionpassesthrough.
intmyFunc(){staticintcount=0;//holds#ofcallstofunctioncount++;}
StaticGlobalVariablesOnelastplacewherethestatickeywordcanbeappliedistoglobalvariables.Thiswilllimittheaccessibilityofthevariabletoonlythecurrentsourcefile,andcanthereforebeusedtohelpavoidnamingconflicts.
//OnlyvisiblewithinthissourcefilestaticintmyGlobal;
CHAPTER18
Enum
Enumisauser-definedtypeconsistingofafixedlistofnamedconstants.Intheexamplebelow,theenumerationtypeiscalledColorandcontainsthreeconstants:Red,GreenandBlue.
enumColor{Red,Green,Blue};
TheColortypecanbeusedtocreatevariablesthatmayholdoneoftheseconstantvalues.
intmain(){Colorc=Red;}
Enumconstantsmaybeprefixedwiththeenumnameforaddedclarity.However,theseconstantsarealwaysunscoped,andsocaremustbetakentoavoidnamingconflicts.
Colorc=Color::Red;
EnumExampleTheswitchstatementprovidesagoodexampleofwhenenumerationscanbeuseful.Comparedtousingordinaryconstants,theenumerationhastheadvantagethatitallowstheprogrammertoclearlyspecifywhatvaluesavariableshouldcontain.
switch(c){caseRed:break;caseGreen:break;caseBlue:break;}
EnumConstantValuesUsuallythereisnoneedtoknowtheunderlyingvaluesthattheconstantsrepresent,butinsomecasesit
canbeuseful.Bydefault,thefirstconstantintheenumlisthasthevaluezeroandeachsuccessiveconstantisonevaluehigher.
enumColor{Red//0Green//1Blue//2};
Thesedefaultvaluescanbeoverriddenbyassigningvaluestotheconstants.Thevaluescanbecomputedanddonothavetobeunique.
enumColor{Red=5,//5Green=Red,//5Blue=Green+2//7};
EnumConversionsThecompilercanimplicitlyconvertanenumerationconstanttoaninteger.However,convertinganintegerbackintoanenumvariablerequiresanexplicitcast,sincethisconversionmakesitpossibletoassignavaluethatisnotincludedintheenum’slistofconstants.
inti=Red;Colorc=(Color)i;
EnumScopeAnenumdoesnothavetobedeclaredglobally.Itcanalsobeplacedwithinaclassasaclassmember,orlocallywithinafunction.
classMyClass{enumColor{Red,Green,Blue};};
voidmyFunction(){enumColor{Red,Green,Blue};}
StronglyTypedEnumsTheenumclasswasintroducedinC++11toprovideasaferalternativetotheregularenum.Thesenewenumsaredefinedinthesamewayasregularenums,withtheadditionoftheclasskeyword.
enumclassSpeed{Fast,Normal,Slow};
Withthenewenumthespecifiedconstantsbelongwithinthescopeoftheenumclassname,asopposedtotheouterscopeasforregularenums.Toaccessanenumclassconstant,itmustthereforebequalifiedwiththeenumname.
Speeds=Speed::Fast;
Theunderlyingintegraltypeoftheregularenumisnotdefinedbythestandardandmayvarybetweenimplementations.Incontrast,aclassenumalwaysusestheinttypebydefault.Thistypecanbeoverriddentoanotherintegertype,asseenbelow.
enumclassMyEnum:unsignedshort{};
Onelastimportantadvantageofenumclassesistheirtypesafety.Unlikeregularenums,enumclassesarestronglytypedandwillthereforenotconvertimplicitlytointegertypes.
if(s==Speed::Fast){}//okif(s==0){}//error
CHAPTER19
StructandUnion
StructAstructinC++isequivalenttoaclass,exceptthatmembersofastructdefaulttopublicaccess,insteadofprivateaccessasinclasses.Byconvention,structsareusedinsteadofclassestorepresentsimpledatastructuresthatmainlycontainpublicfields.
structPoint{intx,y;//public};
classPoint{intx,y;//private};
DeclaratorListTodeclareobjectsofastructthenormaldeclarationsyntaxcanbeused.
Pointp,q;//objectdeclarations
Anotheralternativesyntaxoftenusedwithstructsistodeclaretheobjectswhenthestructisdefinedbyplacingtheobjectnamesbeforethefinalsemicolon.Thispositionisknownasthedeclaratorlistandcancontainacomma-separatedsequenceofdeclarators.
structPoint{intx,y;}r,s;//objectdeclarations
Aggregateinitializationisalsocommonlyusedwithstructs,sincethissyntacticalshortcutonlyworksforsimpleaggregatetypeswithpublicfields.ForcompilerssupportingC++11,theuniforminitialization
syntaxispreferred,asitremovesthedistinctionbetweeninitializationofaggregateandnon-aggregatetypes.
intmain(){//AggregateinitializationPointp={2,3};
//UniforminitializationPointq{2,3};}
UnionAlthoughsimilartostruct,theuniontypeisdifferentinthatallfieldssharethesamememoryposition.Therefore,thesizeofaunionisthesizeofthelargestfielditcontains.Forexample,inthecasebelowthisistheintegerfieldwhichis4byteslarge.
unionMix{charc;//1byteshorts;//2bytesinti;//4bytes}m;
Thismeansthattheuniontypecanonlybeusedtostoreonevalueatatime,becausechangingonefieldwilloverwritethevalueoftheothers.
intmain(){m.c=0xFF;//setfirst8bitsm.s=0;//resetfirst16bits}
Thebenefitofaunion,inadditiontoefficientmemoryusage,isthatitprovidesmultiplewaysofviewingthesamememorylocation.Forexample,theunionbelowhasthreedatamembersthatallowaccesstothesamegroupof4bytesinmultipleways.
unionMix{charc[4];//4bytesstruct{shorthi,lo;}s;//4bytesinti;//4bytes}m;
Theintegerfieldwillaccessall4bytesatonce.Withthestruct2bytescanbeviewedatatime,andbyusingthechararrayeachbytecanbereferencedindividually.
intmain(){m.i=0xFF00F00F;//11111111000000001111000000001111m.s.lo;//1111111100000000m.s.hi;//1111000000001111m.c[3];//11111111m.c[2];//00000000m.c[1];//11110000m.c[0];//00001111}
AnonymousUnionAuniontypecanbedeclaredwithoutaname.Thisiscalledananonymousunionanddefinesanunnamedobjectwhosememberscanbeaccesseddirectlyfromthescopewhereitisdeclared.Ananonymousunioncannotcontainmethodsornon-publicmembers.
intmain(){union{shorts;};//definesanunnamedunionobjects=15;}
Ananonymousunionthatisdeclaredgloballymustbemadestatic.
staticunion{};
CHAPTER20
OperatorOverloading
Operatoroverloadingallowsoperatorstoberedefinedandusedwhereoneorbothoftheoperandsareofauser-definedclass.Whendonecorrectly,thiscansimplifythecodeandmakeuser-definedtypesaseasytouseastheprimitivetypes.
OperatorOverloadingExampleIntheexamplebelowthereisaclasscalledMyNumwithanintegerfieldandaconstructorforsettingthatfield.TheclassalsohasanadditionmethodthataddstwoMyNumobjectstogetherandreturnstheresultasanewobject.
classMyNum{public:intval;MyNum(inti):val(i){}
MyNumadd(MyNum&a){returnMyNum(val+a.val);}}
TwoMyNuminstancescanbeaddedtogetherusingthismethod.
MyNuma=MyNum(10),b=MyNum(5);MyNumc=a.add(b);
BinaryOperatorOverloadingWhatoperatoroverloadingdoesissimplifythissyntaxandtherebyprovideamoreintuitiveinterfacefortheclass.Toconverttheaddmethodtoanoverloadfortheadditionsign,replacethenameofthemethodwiththeoperatorkeywordfollowedbytheoperatorthatistobeoverloaded.Thewhitespacebetweenthekeywordandtheoperatorcanoptionallybeleftout.
MyNumoperator+(MyNum&a){returnMyNum(val+a.val);}
Sincetheclassnowoverloadstheadditionsign,thisoperatorcanbeusedtoperformthecalculationneeded.
MyNumc=a+b;
Keepinmindthattheoperatorisonlyanalternativesyntaxforcallingtheactualmethod.
MyNumd=a.operator+(b);
UnaryOperatorOverloadingAdditionisabinaryoperator,becauseittakestwooperands.Thefirstoperandistheobjectfromwhichthemethodiscalled,andthesecondoperandisthatwhichispassedtothemethod.Whenoverloadingaunaryoperator,suchasprefixincrement(++),thereisnoneedforamethodparametersincetheseoperatorsonlyaffecttheobjectfromwhichtheyarecalled.
Withunaryoperators,areferenceofthesametypeastheobjectshouldalwaysbereturned.Thisisbecausewhenusingaunaryoperatoronanobject,programmersexpecttheresulttoreturnthesameobjectandnotjustacopy.Ontheotherhand,whenusingabinaryoperator,programmersexpectacopyoftheresulttobereturnedandthereforereturnbyvalueshouldbeused.
MyNum&operator++()//++prefix{++val;return*this;}
Notallunaryoperatorsshouldreturnbyreference.Thetwopostfixoperators–post-incrementandpost-decrement–shouldinsteadreturnbyvalue,becausethepostfixoperationsareexpectedtoreturnthestateoftheobjectbeforetheincrementordecrementoccurs.Notethatthepostfixoperatorshaveanunusedintparameterspecified.Thisparameterisusedtodistinguishthemfromtheprefixoperators.
MyNumoperator++(int)//postfix++{MyNumt=MyNum(val);++val;returnt;}
OverloadableOperatorsC++allowsoverloadingofalmostalloperatorsinthelanguage.Ascanbeseeninthetablebelow,mostoperatorsareofthebinarytype.Onlyafewofthemareunary,andsomespecialoperatorscannotbecategorizedaseither.Therearealsosomeoperatorsthatcannotbeoverloadedatall.
Binaryoperators Unaryoperators
+-*/% +-!~&*++--
=+=-=*=/=%= Specialoperators
&= ̂=|=<<=>>= ()[]deletenew
==!=><>=<= Notoverloadable
&| ̂<<>>&&|| ..*::?:###sizeof
–>–>*,
CHAPTER21
CustomConversions
Customtypeconversionscanbedefinedtoallowanobjecttobeconstructedfromorconvertedtoanothertype.Inthefollowingexample,thereisaclasscalledMyNumwithasingleintegerfield.Withconversionconstructorsitispossibletoallowintegertypestobeimplicitlyconvertedtothisobject’stype.
classMyNum{public:intvalue;};
ImplicitConversionConstructorForthistypeconversiontowork,aconstructorneedstobeaddedthattakesasingleparameterofthedesiredtype,inthiscaseanint.
classMyNum{public:intvalue;MyNum(inti){value=i;}};
WhenanintegerisassignedtoanobjectofMyNumthisconstructorwillimplicitlybecalledtoperformthetypeconversion.
MyNumA=5;//implicitconversion
Thismeansthatanyconstructorthattakesexactlyoneargumentcanbeusedbothforconstructingobjectsandforperformingimplicittypeconversionstothatobjecttype.
MyNumB=MyNum(5);//objectconstructionMyNumC(5);//objectconstruction
Theseconversionswillworknotonlyforthespecificparametertype,butalsoforanytypethatcanbeimplicitlyconvertedtoit.Forexample,acharcanbeimplicitlyconvertedtoanintandcantherefore
beimplicitlychangedintoaMyNumobjectaswell.
MyNumD='H';//implicitconversion(char->int->MyNum)
ExplicitConversionConstructorTohelppreventpotentiallyunintendedobjecttypeconversionsitispossibletodisabletheseconduseofthesingleparameterconstructor.Theexplicitconstructormodifieristhenapplied,whichspecifiesthattheconstructormayonlybeusedforobjectconstruction,andnotfortypeconversion.
classMyNum{public:intvalue;explicitMyNum(inti){value=i;}};
Theexplicitconstructorsyntaxmustthereforebeusedtocreateanewobject.
MyNumA=5;//errorMyNumB(5);//allowedMyNumC=MyNum(5);//allowed
ConversionOperatorsCustomconversionoperatorsallowconversionstobespecifiedintheotherdirection:fromtheobject’stypetoanothertype.Theoperatorkeywordisthenused,followedbythetargettype,asetofparentheses,andamethodbody.Thebodyreturnsavalueofthetargettype,inthiscaseint.
classMyNum{public:intvalue;operatorint(){returnvalue;}};
Whenobjectsofthisclassareevaluatedinanintcontext,thisconversionoperatorwillbecalledtoperformthetypeconversion.
MyNumA{5};inti=A;//5
ExplicitConversionOperators
TheC++11standardaddedexplicitconversionoperatorstothelanguage.Similartoexplicitconstructors,theinclusionoftheexplicitkeywordpreventstheconversionoperatorfrombeingimplicitlycalled.
classTrue{explicitoperatorbool()const{returntrue;}};
Theclassaboveprovidesasafeboolthatpreventsitsobjectsfrommistakenlybeingusedinamathematicalcontextthroughtheboolconversionoperator.Intheexamplebelow,thefirstcomparisonresultsinacompileerrorsincetheboolconversionoperatorcannotbeimplicitlycalled.Thesecondcomparisonisallowedbecausetheconversionoperatorisexplicitlycalledthroughthetypecast.
Truea,b;if(a==b){}//errorif((bool)a==(bool)b){}//allowed
Bearinmindthatcontextsrequiringaboolvalue,suchastheconditionforanifstatement,countsasexplicitconversions.
if(a){}//allowed
CHAPTER22
Namespaces
Namespacesareusedtoavoidnamingconflictsbyallowingentities,suchasclassesandfunctions,tobegroupedunderaseparatescope.Intheexamplebelowtherearetwoclassesthatbelongtotheglobalscope.Sincebothclassessharethesamenameandscopethecodewillnotcompile.
classTable{};classTable{};//error:classtyperedefinition
Onewaytosolvethisproblemwouldbetorenameoneoftheconflictingclasses.Anothersolutionistogrouponeorbothofthemunderadifferentnamespacebyenclosingeachinanamespaceblock.Theclassesthenbelongtodifferentscopesandsowillnolongercauseanamingconflict.
namespacefurniture{classTable{};}
namespacehtml{classTable{};}
AccessingNamespaceMembersToaccessamemberofanamespacefromoutsidethatnamespacethemember’sfullyqualifiednameneedstobespecified.Thismeansthatthemembernamehastobeprefixedwiththenamespaceitbelongsto,followedbythescoperesolutionoperator.
intmain(){furniture::TablefTable;html::TablehTable;}
NestingNamespacesItispossibletonestnamespacesanynumberoflevelsdeeptofurtherstructuretheprogramentities.
namespacefurniture{namespacewood{classTable{};}}
Ensurethatthenestednamespacemembersarequalifiedwiththefullnamespacehierarchywhenusingthemfromanothernamespace.
furniture::wood::TablefTable;
ImportingNamespacesToavoidhavingtospecifythenamespaceeverytimeoneofitsmembersisused,thenamespacecanbeimportedintotheglobalorlocalscopewiththehelpofausingdeclaration.Thisdeclarationincludestheusingnamespacekeywordsfollowedbythenamespacetobeimported.Itcanbeplacedeitherlocallyorglobally.Locally,thedeclarationwillonlybeinscopeuntiltheendofthecodeblock,whileattheglobalscopeitwillapplytothewholesourcefilefollowingitsdeclaration.
usingnamespacehtml;//globalnamespaceimportintmain(){usingnamespacehtml;//localnamespaceimport}
Keepinmindthatimportinganamespaceintotheglobalscopedefeatsthemainpurposeofusingnamespaces,whichistoavoidnamingconflicts.Suchconflictshoweveraremainlyanissueinprojectsthatuseseveralindependentlydevelopedcodelibraries.
NamespaceMemberImportIfyouwanttoavoidbothtypingthefullyqualifiednameandimportingthewholenamespacethereisathirdalternativeavailable.Thatistoonlyimportthespecificmembersthatareneededfromthenamespace.Thisisdonebydeclaringonememberatatimewiththeusingkeywordfollowedbythefullyqualifiednamespacemembertobeimported.
usinghtml::Table;//importasinglenamespacemember
NamespaceAlias
Anotherwaytoshortenthefullyqualifiednameistocreateanamespacealias.Thenamespacekeywordisthenusedfollowedbyanaliasname,towhichthefullyqualifiednamespaceisassigned.
namespacemyAlias=furniture::wood;//namespacealias
Thisaliascanthenbeusedinsteadofthenamespacequalifierthatitrepresents.
myAlias::TablefTable;
Notethatboththenamespacememberimportsandthenamespacealiasesmaybedeclaredbothgloballyandlocally.
TypeAliasAliasescanalsobecreatedfortypes.Atypealiasisdefinedusingthetypedefkeywordfollowedbythetypeandthealias.
typedefmy::name::MyClassMyType;
Thealiascanthenbeusedasasynonymforthespecifiedtype.
MyTypet;
Typedefdoesnotonlyworkforexistingtypes,butcanalsoincludeadefinitionofauser-definedtype–suchasaclass,struct,unionorenum.
typedefstruct{intlen;}Length;Lengtha,b,c;
C++11addedausingstatementthatprovidesamoreintuitivesyntaxforaliasingtypes.Withthissyntaxthekeywordusingisfollowedbythealiasnameandthenassignedthetype.Unliketypedeftheusingstatementalsoallowstemplatestobealiased.
usingMyType=my::name::MyClass;
Aliasesarenotcommonlyusedsincetheytendtoobfuscatethecode.However,ifusedproperlyatypealiascansimplifyalongorconfusingtypename.Anotherfunctiontheyprovideistheabilitytochangethedefinitionofatypefromasinglelocation.
IncludingNamespaceMembersKeepinmindthatinC++merelyimportinganamespacedoesnotprovideaccesstothemembersincludedinthatnamespace.Inordertoaccessthenamespacememberstheprototypesalsohavetobemadeavailable,forexamplebyusingtheappropriate#includedirectives.
//Includeinput/outputprototypes#include<iostream>
CHAPTER23
Constants
Aconstantisavariablethathasavaluewhichcannotbechangedoncetheconstanthasbeenassigned.Thisallowsthecompilertoenforcethatthevariable’svalueisnotchangedanywhereinthecodebymistake.
ConstantVariablesAvariablecanbemadeintoaconstantbyaddingtheconstkeywordeitherbeforeorafterthedatatype.Thismodifiermeansthatthevariablebecomesread-only,anditmustthereforebeassignedavalueatthesametimeasitisdeclared.Attemptingtochangethevalueanywhereelseresultsinacompile-timeerror.
constintvar=5;intconstvar2=10;//alternativeorder
ConstantPointersWhenitcomestopointers,constcanbeusedintwoways.First,thepointercanbemadeconstant,whichmeansthatitcannotbechangedtopointtoanotherlocation.
intmyPointee;int*constp=&myPointee;//pointerconstant
Second,thepointeecanbedeclaredconstant.Thismeansthatthevariablepointedtocannotbemodifiedthroughthispointer.
constint*q=&var;//pointeeconstant
Itispossibletodeclareboththepointerandthepointeeasconstanttomakethembothread-only.
constint*constr=&var;//pointer&pointeeconstant
Notethatconstantvariablesmaynotbepointedtobyanon-constantpointer.Thispreventsprogrammersfromaccidentallyrewritingaconstantvariableusingapointer.
int*s=&var;//error:consttonon-constassignment
ConstantReferencesReferencescanbedeclaredconstantinthesamewayaspointers.However,sincereseatingareferenceisneverallowed,declaringthereferenceasconstwouldberedundant.Itonlymakessensetoprotecttherefereefromchange.
constint&y=var;//refereeconstant
ConstantObjectsJustaswithvariables,pointersandreferences,objectscanalsobedeclaredconstant.Takethefollowingclassasanexample.
classMyClass{public:intx;voidsetX(inta){x=a;}};
Aconstantobjectofthisclasscannotbereassignedtoanotherinstance.Theconstnessofanobjectalsoaffectsitsfieldsandpreventthemfrombeingchanged.
constMyClassa,b;a=b;//error:objectisconsta.x=10;//error:objectfieldisconst
ConstantMethodsBecauseofthislastrestriction,aconstantobjectmaynotcallanon-constantmethodsincesuchmethodsareallowedtochangetheobject’sfields.
a.setX(2);//error:cannotcallnon-constmethod
Theymayonlycallconstantmethods,whicharemethodsthataremarkedwiththeconstmodifierbeforethemethodbody.
intgetX()const{returnx;}//constantmethod
Thisconstmodifiermeansthatthemethodisnotallowedtomodifythestateoftheobjectandcanthereforesafelybecalledbyaconstantobjectoftheclass.Morespecifically,theconstmodifierappliestothethispointerthatisimplicitlypassedtothemethod.Thiseffectivelyrestrictsthemethodfrommodifyingtheobject’sfieldsorcallinganynon-constantmethodsintheclass.
ConstantReturnTypeandParametersInadditiontomakingamethodconstant,thereturntypeandmethodparametersmayalsobemaderead-only.Forexample,ifafieldisreturnedbyreferenceinsteadofbyvaluefromaconstantmethoditisimportantthatitisreturnedasaconstantinordertomaintaintheconstnessoftheobject.NotallC++compilerswillbeabletocatchthissubtlemistake.
constint&getX()const{returnx;}
ConstantFieldsBothstaticandinstancefieldsinaclasscanbedeclaredconstant.Aconstantinstancefieldmustbeassigneditsvalueusingtheconstructorinitializationlist.Thisisthesameasthepreferredwayofinitializingregular(non-constant,non-static)fields.
classMyClass{public:inti;constintc;MyClass():c(5),i(5){}}
Aconstantstaticfieldhastobedefinedoutsideoftheclassdeclaration,inthesamewayasnon-constantstaticfields.Theexceptiontothisiswhentheconstantstaticfieldisofanintegerdatatype.Suchafieldmayalsobeinitializedwithintheclassatthesametimeasthefieldisdeclared.
classMyClass{public:staticintsi;conststaticdoublecsd;conststaticintcsi=5;};intMyClass::si=1.23;constdoubleMyClass::csd=1.23;
ConstantExpressionsThekeywordconstexprwasintroducedinC++11toindicateaconstantexpression.Likeconstitcanbeappliedtovariablestomakethemconstant,causingacompilationerrorifanycodeattemptstomodifythevalue.
constexprintmyConst=5;
myConst=3;//error:variableisconst
Unlikeconstvariables,whichmaybeassignedatruntime,aconstantexpressionvariablewillbecomputedatcompiletime.Suchavariablecanthereforealwaysbeusedwhereacompile-timeconstantisneeded,suchasinanarrayandenumdeclarations.PriortoC++11,thiswasonlyallowedforconstantintegerandenumerationtypes.
intmyArray[myConst+1];
Functionsandclassconstructorsmayalsobedefinedasconstantexpressions,whichisnotallowedwithconst.Usingconstexpronafunctionlimitswhatthefunctionisallowedtodo.Inshort,thefunctionmustconsistofasinglereturnstatement,anditcanonlyreferenceotherconstexprfunctionsandglobalconstexprvariables.C++14relaxestheseconstraints,allowingconstexprfunctionstocontainotherexecutablestatements.
constexprintgetDefaultSize(intmultiplier){return3*multiplier;}
Thereturnvalueforaconstexprfunctionisguaranteedtobeevaluatedatcompiletimeonlywhenitsargumentsareconstantexpressionsandthereturnvalueisusedwhereacompile-timeconstantisnecessary.
//Compile-timeevaluationintmyArray[getDefaultSize(10)];
Ifthefunctioniscalledwithoutconstantarguments,itreturnsavalueatruntimejustlikearegularfunction.
//Run-timecallintmul=10;intsize=getDefaultSize(mul);
Constructorscanbedeclaredwithconstexpr,toconstructaconstantexpressionobject.Suchaconstructormustbetrivial.
classCircle{public:intr;constexprCircle(intx):r(x){}};
Whencalledwithaconstantexpressionargument,theresultwillbeacompile-timegeneratedobjectwithread-onlyfields.Withotherargumentsitwillbehaveasanordinaryconstructor.
//Compile-timeobjectconstexprCirclec1(5);
//Run-timeobject
intx=5;Circlec2(x);
ConstantGuidelineIngeneral,itisagoodideatoalwaysdeclarevariablesasconstantsiftheydonotneedtobemodified.Thisensuresthatthevariablesarenotchangedanywhereintheprogrambymistake,whichinturnwillhelptopreventbugs.Thereisalsoaperformancegainbyallowingthecompilertheopportunitytohard-codeconstantexpressionsintothecompiledprogram.Thisallowstheexpressiontobeevaluatedonlyonce–duringcompilation–ratherthaneverytimetheprogramruns.
CHAPTER24
Preprocessor
Thepreprocessorisatextsubstitutiontoolthatmodifiesthesourcecodebeforethecompilationtakesplace.Thismodificationisdoneaccordingtothepreprocessordirectivesthatareincludedinthesourcefiles.Thedirectivesareeasilydistinguishedfromnormalprogrammingcodeinthattheyallstartwithahashsign(#).Theymustalwaysappearasthefirstnon-whitespacecharacteronaline,andtheydonotendwithasemicolon.ThefollowingtableshowsthepreprocessordirectivesavailableinC++alongwiththeirfunctions.
Directive Description
#include Fileinclude
#define Macrodefinition
#undef Macroundefine
#ifdef Ifmacrodefined
#ifndef Ifmacronotdefined
#if If
#elif Elseif
#else Else
#endif Endif
#line Setlinenumber
#error Abortcompilation
#pragma Setcompileroption
IncludingSourceFilesThe#includedirectiveinsertsthecontentsofafileintothecurrentsourcefile.Itsmostcommonuseistoincludeheaderfiles,bothuser-definedandlibraryones.Libraryheaderfilesareenclosedbetweenanglebrackets(<>).Thistellsthepreprocessortosearchfortheheaderinthedefaultdirectorywhereitisconfiguredtolookforstandardheaderfiles.
#include<iostream>//searchlibrarydirectory
Headerfilesthatyoucreateforyourownprogramareenclosedwithindoublequotes("").The
preprocessorwillthensearchforthefileinthesamedirectoryasthecurrentfile.Incasetheheaderisnotfoundthere,thepreprocessorwillthensearchamongthestandardheaderfiles.
#include"MyFile.h"//searchcurrent,thendefault
Thedoublequotedformcanalsobeusedtospecifyanabsoluteorrelativepathtothefile.
#include"C:\MyFile.h"//absolutepath#include"..\MyFile.h"//relativepath
DefineAnotherimportantdirectiveis#define,whichisusedtocreatecompile-timeconstants,alsocalledmacros.Afterthisdirective,thenameoftheconstantisspecifiedfollowedbywhatitwillbereplacedby.
#definePI3.14//macrodefinition
Thepreprocessorwillgothroughandchangeanyoccurrencesofthisconstantwithwhatevercomesafteritinitsdefinitionuntiltheendoftheline.
floatf=PI;//f=3.14
Byconvention,constantsshouldbenamedinuppercaseletterswitheachwordseparatedbyanunderscore.Thatwaytheyareeasytospotwhenreadingthesourcecode.
UndefineA#definedirectiveshouldnotbeusedtodirectlyoverrideapreviouslydefinedmacro.Doingsowillgiveacompilerwarning.Inordertochangeamacro,itfirstneedstobeundefinedusingthe#undefdirective.Attemptingtoundefineamacrothatisnotcurrentlydefinedwillnotgenerateawarning.
#undefPI//undefine#undefPI//allowed
PredefinedMacrosThereareanumberofmacrosthatarepredefinedbythecompiler.Todistinguishthemfromothermacros,theirnamesbeginandendwithtwounderscores.Thesestandardmacrosarelistedinthefollowingtable.
Directive Description
__FILE__ Nameandpathforthecurrentfile.
__LINE__ Currentlinenumber.
__DATE__ CompilationdateinMMDDYYYYformat.
__TIME__ CompilationtimeinHH:MM:SSformat.
__func__ Nameofthecurrentfunction.AddedinC++11.
Acommonuseforpredefinedmacrosistoprovidedebugginginformation.Togiveanexample,thefollowingerrormessageincludesthefilenameandlinenumberwherethemessageoccurs.
cout<<"Errorin"<<__FILE__<<"atline"<<__LINE__;
MacroFunctionsMacroscanbemadetotakearguments.Thisallowsthemtodefinecompile-timefunctions.Forexample,thefollowingmacrofunctiongivesthesquareofitsargument.
#defineSQUARE(x)((x)*(x))
ThemacrofunctioniscalledjustasifitwasaregularC++function.Keepinmindthatforthiskindoffunctiontowork,theargumentsmustbeknownatcompiletime.
intx=SQUARE(2);//4
Notetheextraparenthesesinthemacrodefinitionthatareusedtoavoidproblemswithoperatorprecedence.Withouttheparenthesesthefollowingexamplewouldgiveanincorrectresult,asthemultiplicationwouldthenbecarriedoutbeforetheaddition.
#defineSQUARE(x)x*x
intmain(void){intx=SQUARE(1+1);//1+1*1+1=3}
Tobreakamacrofunctionacrossseverallinesthebackslashcharactercanbeused.Thiswillescapethenewlinecharacterthatmarkstheendofapreprocessordirective.Forthistoworktheremustnotbeanywhitespaceafterthebackslash.
#defineMAX(a,b)\a>b?\a:b
Althoughmacroscanbepowerful,theytendtomakethecodemoredifficulttoreadanddebug.Macrosshouldthereforeonlybeusedwhentheyareabsolutelynecessaryandshouldalwaysbekeptshort.C++codesuchasconstantvariables,enumclasses,andconstexprfunctionscanoftenaccomplishthesamegoalmoreefficientlyandsafelythan#definedirectivescan.
#defineDEBUG0constboolDEBUG=0;
#defineFORWARD1#defineSTOP0#defineBACKWARD-1
enumclassDIR{FORWARD=1,STOP=0,BACKWARD=-1};
#defineMAX(a,b)a>b?a:bconstexprintMAX(inta,intb){returna>b?a:b;}
ConditionalCompilationThedirectivesusedforconditionalcompilationcanincludeorexcludepartofthesourcecodeifacertainconditionismet.First,thereisthe#ifand#endifdirectives,whichspecifiesasectionofcodethatwillonlybeincludediftheconditionafterthe#ifdirectiveistrue.Notethatthisconditionmustevaluatetoaconstantexpression.
#defineDEBUG_LEVEL3
#ifDEBUG_LEVEL>2//...#endif
JustaswiththeC++ifstatement,anynumberof#elif(elseif)directivesandonefinal#elsedirectivecanbeincluded.
#ifDEBUG_LEVEL>2//...#elifDEBUG_LEVEL==2//...#else//...#endif
Conditionalcompilationalsoprovidesausefulmeansoftemporarilycommentingoutlargeblocksofcodefortestingpurposes.Thisoftencannotbedonewiththeregularmultilinecommentsincetheycannotbenested.
#if0/*Removedfromcompilation*/#endif
CompileifDefinedSometimes,asectionofcodeshouldonlybecompiledifacertainmacrohasbeendefined,irrespectiveofitsvalue.Forthispurposetwospecialoperatorscanbeused:definedand!defined(notdefined).
#defineDEBUG
#ifdefinedDEBUG//...
#elif!definedDEBUG//...#endif
Thesameeffectcanalsobeachievedusingthedirectives#ifdefand#ifndefrespectively.Forinstance,the#ifdefsectionisonlycompiledifthespecifiedmacrohasbeenpreviouslydefined.Notethatamacroisconsidereddefinedevenifithasnotbeengivenavalue.
#ifdefDEBUG//...#endif
#ifndefDEBUG//...#endif
ErrorWhenthe#errordirectiveisencounteredthecompilationisaborted.Thisdirectivecanbeusefultodeterminewhetherornotacertainlineofcodeisbeingcompiled.Itcanoptionallytakeaparameterthatspecifiesthedescriptionofthegeneratedcompilationerror.
#errorCompilationaborted
LineAlesscommonlyuseddirectiveis#line,whichcanchangethelinenumberthatisdisplayedwhenanerroroccursduringcompilation.Followingthisdirectivethelinenumberwillasusualbeincreasedbyoneforeachsuccessiveline.Thedirectivecantakeanoptionalstringparameterthatsetsthefilenamethatwillbeshownwhenanerroroccurs.
#line5"myapp.cpp"
PragmaThelaststandarddirectiveis#pragma,orpragmaticinformation.Thisdirectiveisusedtospecifyoptionstothecompiler;andassuch,theyarevendorspecific.Togiveanexample,#pragmamessagecanbeusedwithmanycompilerstooutputastringtothebuildwindow.Anothercommonargumentforthisdirectiveiswarning,whichchangeshowthecompilerhandleswarnings.
//Showcompilermessage#pragmamessage("HelloCompiler")
//Disablewarning4507#pragmawarning(disable:4507)
AttributesAnewstandardizedsyntaxwasintroducedinC++11forprovidingcompilerspecificinformationinthesourcecode,so-calledattributes.Attributesareplacedwithindoublesquarebracketsandmay,dependingontheattribute,beappliedtoanycodeentities.Togiveanexample,astandardattributeaddedinC++14is[[deprecated]],whichindicatesthatuseofacodeentityhasbecomediscouraged.
//Markasdeprecated[[deprecated]]voidfoo(){}
Thisattributeallowsthecompilertoemitawarningwheneversuchanentityisused.Amessagecanbeincludedinthiswarning,todescribewhytheentityhasbeendeprecated.
[[deprecated("foo()isunsafe,usebar()instead")]]voidfoo(){}
CHAPTER25
ExceptionHandling
Exceptionhandlingallowsprogrammerstodealwithunexpectedsituationsthatmayoccurinaprogram.
ThrowingExceptionsWhenafunctionencountersasituationthatitcannotrecoverfromitcangenerateanexceptiontosignalthecallerthatthefunctionhasfailed.Thisisdoneusingthethrowkeywordfollowedbywhateveritisthefunctionwantstosignal.Whenthisstatementisreached,thefunctionwillstopexecutingandtheexceptionwillpropagateuptothecallerwhereitcanbecaught,usingatry-catchstatement.
ntdivide(intx,inty){if(y==0)throw0;returnx/y;}
Try-catchstatementThetry-catchstatementconsistsofatryblockcontainingcodethatmaycauseexceptionsandoneormorecatchclausestohandlethem.Intheabovecaseanintegeristhrownandsoacatchblockneedstobeincludedthathandlesthistypeofexception.Thethrownexpressionwillgetpassedasanargumenttothisexceptionhandler,whereitcanbeusedtodeterminewhathasgonewrongwiththefunction.Notethatwhentheexceptionhasbeenhandled,theexecutionwillthencontinuerunningafterthetry-catchblocksandnotafterthethrowstatement.
try{divide(10,0);}catch(int&e){std::cout<<"Errorcode:"<<e;}
Anexceptionhandlercancatchathrownexpressionbyeithervalue,referenceorpointer.However,
catchingbyvalueshouldbeavoidedsincethiscausesanextracopytobemade.Catchingbyreferenceisgenerallypreferable.Ifthecodeinthetryblockcanthrowmoretypesofexceptionsthenmorecatchclausesneedtobeaddedtohandlethemaswell.Keepinmindthatonlythehandlerthatmatchesthethrownexpressionwillbeexecuted.
catch(char&e){std::cout<<"Errorchar:"<<e;}
Tocatchalltypesofexceptionsanellipsis(...)canbeusedastheparameterofcatch.Thisdefaulthandlermustbeplacedasthelastcatchstatementsincenohandlerplacedafteritwilleverbeexecuted.
catch(...){std::cout<<"Error";}
Re-throwingExceptionsIfanexceptionhandlerisnotabletorecoverfromanexceptionitcanbere-thrownbyusingthethrowkeywordwithnoargumentspecified.Thiswillpasstheexceptionupthecallerstackuntilanothertry-catchblockisencountered.Becarefulhowever,becauseifanexceptionisnevercaughttheprogramwillterminatewitharun-timeerror.
intmain(){try{try{throw0;}catch(...){throw;}//re-throwexception}catch(...){throw;}//run-timeerror}
ExceptionSpecificationFunctionsarebydefaultallowedtothrowexceptionsofanytype.Tospecifytheexceptiontypesthatafunctionmaythrowthethrowkeywordcanbeappendedtothefunctiondeclaration.Thethrowkeywordisfollowedbyacommaseparatedlistoftheallowedtypes,ifany,enclosedinparentheses.
voiderror1(){}//maythrowanyexceptionsvoiderror2()throw(...){}//maythrowanyexceptionsvoiderror3()throw(int){}//mayonlythrowintvoiderror4()throw(){}//maynotthrowexceptions
ThiskindofexceptionspecificationisverydifferentfromtheoneusedinforexampleJava,andoverallthereisverylittlereasontospecifyexceptionsinC++.Thecompilerwillnotenforcethespecifiedexceptionsinanywayanditwillnotbeabletomakeanyoptimizationsbecauseofthem.
UseofthrowforexceptionspecificationwasdeprecatedinC++11andreplacedbyanoexcept
specifier.Similartothrow(),thisspecifierindicatesthatafunctionisintendednottothrowanyexceptions.Themaindifferenceisthatnoexceptenablescertaincompileroptimizations,becausethespecifierallowstheprogramtoterminatewithoutunwindingthecallstackifforanyreasonanexceptionstilloccurs.
voidfoo()noexcept{}//maynotthrowexceptions
ExceptionClassAspreviouslymentioned,anydatatypecanbethrowninC++.However,thestandardlibrarydoesprovideabaseclasscalledexceptionwhichisspecificallydesignedtodeclareobjectstobethrown.Itisdefinedintheexceptionheaderfileandislocatedunderthestdnamespace.Asseenbelow,theclasscanbeconstructedwithastringthatbecomestheexception’sdescription.
#include<exception>voidmake_error(){throwstd::exception("MyErrorDescription");}
Whencatchingthisexceptiontheobject’sfunctionwhatcanbeusedtoretrievethedescription.
try{make_error();}catch(std::exceptione){std::cout<<e.what();}
CHAPTER26
TypeConversions
Convertinganexpressionfromonetypetoanotherisknownastype-conversion.Thiscanbedoneeitherimplicitlyorexplicitly.
ImplicitConversionsAnimplicitconversionisperformedautomaticallybythecompilerwhenanexpressionneedstobeconvertedintooneofitscompatibletypes.Forexample,anyconversionsbetweentheprimitivedatatypescanbedoneimplicitly.
longa=5;//intimplicitlyconvertedtolongdoubleb=a;//longimplicitlyconvertedtodouble
Theseimplicitprimitiveconversionscanbefurthergroupedintotwokinds:promotionanddemotion.Promotionoccurswhenanexpressiongetsimplicitlyconvertedintoalargertypeanddemotionoccurswhenconvertinganexpressiontoasmallertype.Becauseademotioncanresultinthelossofinformation,theseconversionswillgenerateawarningonmostcompilers.Ifthepotentialinformationlossisintentional,thewarningcanbesuppressedbyusinganexplicitcast.
//Promotionlonga=5;//intpromotedtolongdoubleb=a;//longpromotedtodouble
//Demotionintc=10.5;//warning:possiblelossofdataboold=c;//warning:possiblelossofdata
ExplicitConversionsThefirstexplicitcastistheoneinheritedfromC,commonlycalledtheC-stylecast.Thedesireddatatypeissimplyplacedinparenthesestotheleftoftheexpressionthatneedstobeconverted.
intc=(int)10.5;//doubledemotedtoint
chard=(char)c;//intdemotedtochar
C++castsTheC-stylecastissuitableformostconversionsbetweentheprimitivedatatypes.However,whenitcomestoconversionsbetweenclassesandpointersitcanbetoopowerful.InordertogetgreatercontroloverthedifferenttypesofconversionspossibleC++introducedfournewcasts,callednamedcastsornew-stylecasts.Thesecastsare:static,reinterpret,constanddynamiccast.
static_cast<new_type>(expression)reinterpret_cast<new_type>(expression)const_cast<new_type>(expression)dynamic_cast<new_type>(expression)
Asseenabove,theirformatistofollowthecast’snamewiththenewtypeenclosedinanglebracketsandthereaftertheexpressiontobeconvertedinparentheses.Thesecastsallowmoreprecisecontroloverhowaconversionshouldbeperformed,whichinturnmakesiteasierforthecompilertocatchconversionerrors.Incontrast,theC-stylecastincludesthestatic,reinterpretandconstcastinoneoperation.Thatcastisthereforemorelikelytoexecutesubtleconversionerrorsifusedincorrectly.
StaticCastThestaticcastperformsconversionsbetweencompatibletypes.ItissimilartotheC-stylecast,butismorerestrictive.Forexample,theC-stylecastwouldallowanintegerpointertopointtoachar.
charc=10;//1byteint*p=(int*)&c;//4bytes
Sincethisresultsina4-bytepointerpointingto1byteofallocatedmemory,writingtothispointerwilleithercausearun-timeerrororwilloverwritesomeadjacentmemory.
*p=5;//run-timeerror:stackcorruption
IncontrasttotheC-stylecast,thestaticcastwillallowthecompilertocheckthatthepointerandpointeedatatypesarecompatible,whichallowstheprogrammertocatchthisincorrectpointerassignmentduringcompilation.
int*q=static_cast<int*>(&c);//compile-timeerror
ReinterpretCastToforcethepointerconversion,inthesamewayastheC-stylecastdoesinthebackground,thereinterpretcastwouldbeusedinstead.
int*r=reinterpret_cast<int*>(&c);//forcedconversion
Thiscasthandlesconversionsbetweencertainunrelatedtypes,suchasfromonepointertypetoanotherincompatiblepointertype.Itwillsimplyperformabinarycopyofthedatawithoutalteringtheunderlyingbitpattern.Notethattheresultofsuchalow-leveloperationissystem-specificandthereforenotportable.Itshouldbeusedwithcautionifitcannotbeavoidedaltogether.
ConstCastThethirdC++castistheconstcast.Thisoneisprimarilyusedtoaddorremovetheconstmodifierofavariable.
constintmyConst=5;int*nonConst=const_cast<int*>(&a);//removesconst
Althoughconstcastallowsthevalueofaconstanttobechanged,doingsoisstillinvalidcodethatmaycausearun-timeerror.Thiscouldoccurforexampleiftheconstantwaslocatedinasectionofread-onlymemory.
*nonConst=10;//potentialrun-timeerror
Constcastisinsteadusedmainlywhenthereisafunctionthattakesanon-constantpointerargument,eventhoughitdoesnotmodifythepointee.
voidprint(int*p){std::cout<<*p;}
Thefunctioncanthenbepassedaconstantvariablebyusingaconstcast.
print(&myConst);//error:cannotconvert//constint*toint*
print(nonConst);//allowed
C-styleandNew-StyleCastsKeepinmindthattheC-stylecastcanalsoremovetheconstmodifier,butagainsinceitdoesthisconversionbehindthescenestheC++castsarepreferable.AnotherreasontousetheC++castsisthattheyareeasiertofindinthesourcecodethentheC-stylecast.Thisisimportantbecausecastingerrorscanbedifficulttodiscover.AthirdreasonforusingtheC++castsisthattheyareunpleasanttowrite.Sinceexplicitconversioninmanycasescanbeavoided,thiswasdoneintentionallysothatprogrammerswouldlookforadifferentsolution.
DynamicCastThefourthandfinalC++castisthedynamiccast.Thisoneisonlyusedtoconvertobjectpointersandobjectreferencesintootherpointerorreferencetypesintheinheritancehierarchy.Itistheonlycastthat
makessurethattheobjectpointedtocanbeconverted,byperformingarun-timecheckthatthepointerreferstoacompleteobjectofthedestinationtype.Forthisrun-timechecktobepossibletheobjectmustbepolymorphic.Thatis,theclassmustdefineorinheritatleastonevirtualfunction.Thisisbecausethecompilerwillonlygeneratetheneededrun-timetypeinformationforsuchobjects.
DynamicCastExamplesIntheexamplebelow,aMyChildpointerisconvertedintoaMyBasepointerusingadynamiccast.Thisderived-to-baseconversionsucceeds,becausetheChildobjectincludesacompleteBaseobject.
classMyBase{public:virtualvoidtest(){}};classMyChild:publicMyBase{};
intmain(){MyChild*child=newMyChild();MyBase*base=dynamic_cast<MyBase*>(child);//ok}
ThenextexampleattemptstoconvertaMyBasepointertoaMyChildpointer.SincetheBaseobjectdoesnotcontainacompleteChildobjectthispointerconversionwillfail.Toindicatethis,thedynamiccastreturnsanullpointer.Thisgivesaconvenientwaytocheckwhetherornotaconversionhassucceededduringrun-time.
MyBase*base=newMyBase();MyChild*child=dynamic_cast<MyChild*>(base);
if(child==0)std::cout<<"Nullpointerreturned";
Ifareferenceisconvertedinsteadofapointer,thedynamiccastwillthenfailbythrowingabad_castexception.Thisneedstobehandledusingatry-catchstatement.
#include<exception>//...try{MyChild&child=dynamic_cast<MyChild&>(*base);}catch(std::bad_cast&e){std::cout<<e.what();//baddynamic_cast}
DynamicorStaticCastTheadvantageofusingadynamiccastisthatitallowstheprogrammertocheckwhetherornotaconversionhassucceededduringrun-time.Thedisadvantageisthatthereisaperformanceoverheadassociatedwithdoingthischeck.Forthisreasonusingastaticcastwouldhavebeenpreferableinthe
firstexample,becauseaderived-to-baseconversionwillneverfail.
MyBase*base=static_cast<MyBase*>(child);//ok
However,inthesecondexampletheconversionmayeithersucceedorfail.ItwillfailiftheMyBaseobjectcontainsaMyBaseinstanceanditwillsucceedifitcontainsaMyChildinstance.Insomesituationsthismaynotbeknownuntilrun-time.Whenthisisthecasedynamiccastisabetterchoicethanstaticcast.
//SucceedsforaMyChildobjectMyChild*child=dynamic_cast<MyChild*>(base);
Ifthebase-to-derivedconversionhadbeenperformedusingastaticcastinsteadofadynamiccasttheconversionwouldnothavefailed.Itwouldhavereturnedapointerthatreferredtoanincompleteobject.Dereferencingsuchapointercanleadtorun-timeerrors.
//Allowed,butinvalidMyChild*child=static_cast<MyChild*>(base);
//IncompleteMyChildobjectdereferenced(*child);
CHAPTER27
Templates
Templatesprovideawaytomakeaclass,function,orvariableoperatewithdifferentdatatypeswithouthavingtorewritethecodeforeachtype.
FunctionTemplatesTheexamplebelowshowsafunctionthatswapstwointegerarguments.
voidswap(int&a,int&b){inttmp=a;a=b;b=tmp;}
Toconvertthismethodintoafunctiontemplatethatcanworkwithanytypethefirststepistoaddatemplateparameterdeclarationbeforethefunction.Thisdeclarationincludesthetemplatekeywordfollowedbythekeywordclassandthenameofthetemplateparameter,bothenclosedbetweenanglebrackets.Thenameofthetemplateparametermaybeanything,butitiscommontonameitwithacapitalT.
template<classT>
Alternatively,thekeywordtypenamecanbeusedinsteadofclass.Theyarebothequivalentinthiscontext.
template<typenameT>
Thesecondstepincreatingafunctiontemplateistoreplacethedatatypethatwillbemadegenericwiththetemplateparameter.
template<classT>voidswap(T&a,T&b){Ttmp=a;a=b;
b=tmp;}
CallingFunctionTemplatesThefunctiontemplateisnowcomplete.Touseitswapcanbecalledasifitwasaregularfunction,butwiththedesiredtemplateargumentspecifiedinanglebracketsbeforethefunctionarguments.Behindthescenes,thecompilerwillinstantiateanewfunctionwiththistemplateparameterfilledin,anditisthisgeneratedfunctionthatwillbecalledfromthisline.
inta=1,b=2;swap<int>(a,b);//callsintversionofswap
Everytimethefunctiontemplateiscalledwithanewtype,thecompilerwillinstantiateanotherfunctionusingthetemplate.
boolc=true,d=false;swap<bool>(c,d);//callsboolversionofswap
Inthisexample,theswapfunctiontemplatemayalsobecalledwithoutspecifyingthetemplateparameter.Thisisbecausethecompilercanautomaticallydeterminethetype,becausethefunctiontemplate’sargumentsusethetemplatetype.However,ifthisisnotthecase,orifthereisaneedtoforcethecompilertoselectaspecificinstantiationofthefunctiontemplate,thetemplateparameterwouldthenneedtobeexplicitlyspecifiedwithinanglebrackets.
inte=1,f=2;swap(e,f);//callsintversionofswap
MultipleTemplateParametersTemplatescanbedefinedtoacceptmorethanonetemplateparameterbyaddingthembetweentheanglebrackets.
template<classT,classU>voidswap(T&a,U&b){Ttmp=a;a=b;b=tmp;}
Thesecondtemplateparameterintheexampleaboveallowsswaptobecalledwithtwoargumentsofdifferenttypes.
intmain(){
inta=1;longb=2;swap<int,long>(a,b);}
ClassTemplatesClasstemplatesallowclassmemberstousetemplateparametersastypes.Theyarecreatedinthesamewayasfunctiontemplates.
template<classT>classmyBox{public:Ta,b;};
Unlikefunctiontemplates,aclasstemplatemustalwaysbeinstantiatedwithexplicitlyspecifiedtemplateparameters.
myBox<int>box;
Anotherthingtorememberwhenusingclasstemplatesisthatifamethodisdefinedoutsideoftheclasstemplatethatdefinitionmustalsobeprecededbythetemplatedeclaration.
template<classT>classmyBox{public:Ta,b;voidswap();};
template<classT>voidmyBox<T>::swap(){Ttmp=a;a=b;b=tmp;}
Noticethatthetemplateparameterisincludedintheswaptemplatefunctiondefinitionaftertheclassnamequalifier.Thisspecifiesthatthefunction’stemplateparameteristhesameasthetemplateparameteroftheclass.
Non-TypeParametersInadditiontotypeparameters,templatescanalsohaveregularfunction-likeparameters.Asanexample,theinttemplateparameterbelowisusedtospecifythesizeofanarray.
template<classT,intN>classmyBox{public:Tstore[N];};
Whenthisclasstemplateisinstantiated,bothatypeandanintegerhavetobeincluded.
myBox<int,5>box;
DefaultTypesandValuesClasstemplateparameterscanbegivendefaultvaluesandtypes.
template<classT=int,intN=5>
Tousethesedefaultstheanglebracketsjustneedtobeleftemptywheninstantiatingtheclasstemplate.
myBox<>box;
Notethatdefaulttemplateparametersmaynotbeusedinfunctiontemplates.
ClassTemplateSpecializationIfthereisaneedtodefineadifferentimplementationforatemplatewhenaspecifictypeispassedasthetemplateparameter,atemplatespecializationcanbedeclared.Forexample,inthefollowingclasstemplatethereisaprintmethodthatoutputsthevalueofatemplatevariable.
#include<iostream>
template<classT>classmyBox{public:Ta;voidprint(){std::cout<<a;}};
Whenthetemplateparameterisaboolthemethodshouldprintout“true”or“false”insteadof“1”or“0”.Onewaytodothiswouldbetocreateaclasstemplatespecialization.Areimplementationoftheclasstemplateisthencreatedwherethetemplateparameterlistisempty.Instead,aboolspecializationparameterisplacedaftertheclasstemplate’snameandthisdatatypeisusedinsteadofthetemplateparameterthroughouttheimplementation.
template<>classmyBox<bool>{public:boola;voidprint(){std::cout<<(a?"true":"false");}};
Whenthisclasstemplateisinstantiatedwithabooltemplatetype,thistemplatespecializationwillbeusedinsteadofthestandardone.
intmain(){myBox<bool>box={true};box.print();//"true"}
Notethatthereisnoinheritanceofmembersfromthestandardtemplatetothespecializedtemplate.Thewholeclasswillhavetoberedefined.
FunctionTemplateSpecializationSincethereisonlyonefunctionthatisdifferentbetweenthetemplatesintheexampleabove,abetteralternativewouldbetocreateafunctiontemplatespecialization.Thiskindofspecializationlooksverysimilartotheclasstemplatespecialization,butisonlyappliedtoasinglefunctioninsteadofthewholeclass.
#include<iostream>
template<classT>classmyBox{public:Ta;
template<classT>voidprint(){std::cout<<a;}
template<>voidprint<bool>(){std::cout<<(a?"true":"false");
}};
Thiswayonlytheprintmethodhastoberedefinedandnotthewholeclass.
intmain(){myBox<bool>box={true};box.print<bool>();//"true"}
Noticethatthetemplateparameterhastobespecifiedwhenthespecializedfunctionisinvoked.Thisisnotthecasewiththeclasstemplatespecialization.
VariableTemplatesInadditiontofunctionandclasstemplates,C++14allowsvariablestobetemplated.Thisisachievedusingtheregulartemplatesyntax.
template<classT>constexprTpi=T(3.1415926535897932384626433L);
Togetherwiththeconstexprspecifier,thistemplateallowsthevalueofthevariabletobecomputedatcompiletimeforagiventype,withouthavingtotypecastthevalue.
inti=pi<int>;//3floatf=pi<float>;//3.14...
VariadicTemplatesC++11allowstemplatedefinitionstotakeavariablenumberoftypearguments.Thisfeaturecanbeusedasareplacementforvariadicfunctions.Toillustrate,considerthefollowingvariadicfunction,whichreturnsthesumofanynumberofintspassedtoit.
#include<iostream>#include<initializer_list>usingnamespacestd;
intsum(initializer_list<int>numbers){inttotal=0;for(auto&i:numbers){total+=i;}returntotal;}
Theinitializer_listtypeindicatesthatthefunctionacceptsabrace-enclosedlistasitsargument,sothe
functionmustbecalledinthismanner.
intmain(){cout<<sum({1,2,3});//"6"}
Thenextexamplechangesthisfunctionintoavariadictemplatefunction.Suchafunctionistraversedrecursivelyratherthaniteratively,sooncethefirstargumenthasbeenhandledthefunctioncallsitselfwiththeremainingarguments.
Thevariadictemplateparameterisspecifiedusingtheellipsis(...)operator,followedbyaname.Thisdefinesaso-calledparameterpack.Theparameterpackishereboundtoaparameterinthefunction(...rest),andthenunpackedintoseparatearguments(rest...)whenthefunctioncallsitselfrecursively.
intsum(){return0;}//endcondition
template<classT0,class...Ts>decltype(auto)sum(T0first,Ts...rest){returnfirst+sum(rest...);}
Thisvariadictemplatefunctioncanbecalledasaregularfunction,withanynumberofarguments.Incontrasttothepreviouslydefinedvariadicfunction,thistemplatefunctionacceptsargumentsofanytype.
intmain(){cout<<sum(1,1.5,true);//"3.5"}
CHAPTER28
Headers
Whenaprojectgrowsitiscommontosplitthecodeupintodifferentsourcefiles.Whenthishappenstheinterfaceandimplementationaregenerallyseparated.Theinterfaceisplacedinaheaderfile,whichcommonlyhasthesamenameasthesourcefileanda.hfileextension.Thisheaderfilecontainsforwarddeclarationsforthesourcefileentitiesthatneedtobeaccessibletoothercompilationunitsintheproject.Acompilationunitconsistsofasourcefile(.cpp)plusanyincludedheaderfiles(.hor.hpp).
WhytoUseHeadersC++requireseverythingtobedeclaredbeforeitcanbeused.Itisnotenoughtosimplycompilethesourcefilesinthesameproject.Forexample,ifafunctionisplacedinMyFunc.cpp,andasecondfilenamedMyApp.cppinthesameprojecttriestocallit,thecompilerwillreportthatitcannotfindthefunction.
//MyFunc.cppvoidmyFunc(){}
//MyApp.cppintmain(){myFunc();//error:myFuncidentifiernotfound}
Tomakethisworkthefunction’sprototypehastobeincludedinMyApp.cpp.
//MyApp.cppvoidmyFunc();//prototype
intmain(){myFunc();//ok}
UsingHeadersThiscanbemademoreconvenientiftheprototypeisplacedinaheaderfilenamedMyFunc.handthisheaderisincludedinMyApp.cppthroughtheuseofthe#includedirective.ThiswayifanychangesaremadetoMyFuncthereisnoneedtoupdatetheprototypesinMyApp.cpp.Furthermore,anysourcefilethatwantstousethesharedcodeinMyFunccanjustincludethisoneheader.
//MyFunc.hvoidmyFunc();//prototype
//MyApp.cpp#include"MyFunc.h"
WhattoIncludeinHeadersAsfarasthecompilerisconcernedthereisnodifferencebetweenaheaderfileandasourcefile.Thedistinctionisonlyconceptual.Thekeyideaisthattheheadershouldcontaintheinterfaceoftheimplementationfile–thatis,thecodethatothersourcefileswillneedtouse.Thismayincludesharedconstants,macros,andtypealiases.
//MyApp.h-Interface#defineDEBUG0constdoubleE=2.72;typedefunsignedlongulong;
Asalreadymentioned,theheadercancontainprototypesofthesharedfunctionsdefinedinthesourcefile.
voidmyFunc();//prototype
Additionally,sharedclassesaretypicallyspecifiedintheheader,whiletheirmethodsareimplementedinthesourcefile.
//MyApp.hclassMyClass{public:voidmyMethod();};
//MyApp.cppvoidMyClass::myMethod(){}
Aswithfunctions,itisnecessarytoforwarddeclareglobalvariablesbeforetheycanbereferencedinacompilationunitoutsidetheonecontainingtheirdefinition.Thisisdonebyplacingthesharedvariableintheheaderandmarkingitwiththekeywordextern.Thiskeywordindicatesthatthevariableisinitializedinanothercompilationunit.Functionsareexternbydefault,sofunctionprototypesdonotneedtoincludethisspecifier.Keepinmindthatglobalvariablesandfunctionsmaybedeclaredexternally
multipletimesinaprogram,buttheymaybedefinedonlyonce.
//MyApp.hexternintmyGlobal;
//MyApp.cppintmyGlobal=0;
Itshouldbenotedthattheuseofsharedglobalvariablesisdiscouraged.Thisisbecausethelargeraprogrambecomes,themoredifficultitistokeeptrackofwhichfunctionsaccessandmodifythesevariables.Thepreferredmethodistoinsteadpassvariablestofunctionsonlyasneeded,inordertominimizethescopeofthosevariables.
Theheadershouldnotincludeanyexecutablestatements,withtwoexceptions.First,ifasharedclassmethodorglobalfunctionisdeclaredasinline,thatfunctionmustbedefinedintheheader.Otherwise,callingtheinlinefunctionfromanothersourcefilewillgiveanunresolvedexternalerror.Notethattheinlinemodifiersuppressesthesingledefinitionrulethatnormallyappliestocodeentities.
//MyApp.hinlinevoidinlineFunc(){}
classMyClass{public:voidinlineMethod(){}};
Thesecondexceptionissharedtemplates.Whenencounteringatemplateinstantiation,thecompilerneedstohaveaccesstotheimplementationofthattemplate,inordertocreateaninstanceofitwiththetypeargumentsfilledin.Thedeclarationandimplementationoftemplatesarethereforegenerallyputintotheheaderfilealltogether.
//MyApp.htemplate<classT>classMyTemp{/*...*/}
//MyApp.cppMyTemp<int>o;
Instantiatingatemplatewiththesametypeinmanycompilationunitsleadstosignificantredundantworkdonebythecompilerandlinker.TopreventthisC++11introducedexterntemplatedeclarations.Atemplateinstantiationmarkedasexternsignalstothecompilernottoinstantiatethetemplateinthiscompilationunit.
//MyApp.cppMyTemp<int>b;//instantiationisdonehere
//MyFunc.cppexternMyTemp<int>a;//supressredundantinstantiation
Ifaheaderrequiresotherheadersitiscommontoincludethosefilesaswell,tomaketheheaderstand
alone.Thisensuresthateverythingneededisincludedinthecorrectorder,solvingpotentialdependencyproblemsforeverysourcefilethatrequirestheheader.
//MyApp.h#include<cstddef.h>//includesize_tvoidmySize(std::size_t);
Notethatsinceheadersmainlycontaindeclarations,anyextraheadersincludedshouldnotaffectthesizeoftheprogram,althoughtheymayslowdowncompilation.
IncludeGuardsAnimportantthingtobearinmindwhenusingheaderfilesisthatasharedcodeentitymayonlybedefinedonce.Consequently,includingthesameheaderfilemorethanoncewilllikelyresultincompilationerrors.Thestandardwaytopreventthisistouseaso-calledincludeguard.Anincludeguardiscreatedbyenclosingthestartoftheheaderina#ifndefsectionthatchecksforamacrospecifictothatheaderfile.Onlywhenthemacroisnotdefinedisthefileincludedandthemacroisthendefined,whicheffectivelypreventsthefilefrombeingincludedagain.
//MyApp.h#ifndefMYAPP_H#defineMYAPP_H//...#endif//MYAPP_H
Index
A,BAccesslevel
friendmodifierglobalfunctioninheritedmembersprivateaccessprotectedaccesspublicaccess
AnonymousunionArrays
assignmentdeclarationandallocationdynamicarraysmulti-dimensionalsize
Ccin::getfunctionClass
forwarddeclarationinlinemethodsmethodsobjectcreationobjectmembers
CommentsConditionalstatements
ifstatementswitchstatementternaryoperator
ConsolecompilationConstants
argumentsconstexprfunctionsconstkeywordexpressionsmethodparametersmethodsnon-constantpointerobjectpointersreferencesreturntypestaticfield
ConstcastConstructors
aggregateintializationcopyintializationdefaultconstructordestructordirectintializationfieldinitializationinstancemethodsnewinitialization
objectintializationoverloadingspecialmemberfunctionsuniforminitializationvalueintialization
C-stylecastCustomtypeconversions
explicitconversionimplicitconversionoperatorkeywords
DDynamicallocationDynamiccast
EEnum
classkeywordconstantvaluesconversionsscopeswitchstatement
Exceptionhandlingexceptionstypesre-throwexceptionsstdnamespacethrowkeywordtry-catchstatementwhat()function
Explicitconversions
F,GFunctions
argumentsautokeywordcallingfunctionsdecltypekeyworddefaultvaluedefinitioninlinefunctionjumpstatementlambdafunctionsoverloadingparameterspassedbyaddresspassedbyreferencepassedbyvalueprototypedeclarationreturnbyaddressreturnbyreferencereturnbyvaluereturnstatement
HHeaders
#includedirectiveincludeguardsinlinemodifierMyApp.cppMyFunccpp
sharedclassestemplates
I,J,KImplicitconversionsInheritance
constructordowncastmultipleupcast
IntegratedDevelopmentEnvironment(IDE)IntelliSenseIostreamheader
L,MLoopstatements
breakandcontinuestatementsdo-whileloopgotostatementsforloopwhileloop
NNamespaces
aliasdeclarationincludedirectivesmemberimportmembersaccessnestingtypealias
NullpointerNumericaloperators
arithmeticassignmentbitwisecombinedassignmentcomparisondefinitionincrementanddecrementlogical
OOperatoroverloading
binaryunary
OperatorprecedenceOverloadableoperatorsOverriding
baseclassscopingfinalmodifierRectanglegetAreamethodTrianglegetAreamethodvirtualmethod
P,QPointer
creationdefinition
dereferenceoperatordynamicallocationnullpointer
Preprocessorattributes#definedirective#elifdirectives#elsedirectives#endifdirectives#errordirectives#ifdefdirectives#ifdirectives#ifndefdirectives#includedirective#linedirectivesmacrofunctions#pragmadirectivespredefinedmacros#undefdirective
RReferences
creationpointersrvalue
Reinterpretcast
SSolutionExplorerpaneStaticcastStaticfieldsStaticglobalvariablesStaticlocalvariablesStaticmethodsString
combinationcomparsionencodingsescapecharactersfunctions
Structdeclaratorlist
TTemplates
callingfunctionclasstemplatesclasstemplatespecializationdefaultvaluesandtypesfunctionfunctionspecializationmultipletemplateparametersnon-typeparametersswapfunctiontemplateparametertemplatespecializationvariablefunctionvariadicfunction
Type-conversionconstcastC-stylecast
dynamiccastexplicitimplicitreinterpretcaststaticcast
UUniontype
V,W,X,Y,ZVariables
assignmentoperatorBooleanvaluechartypeconstructorinitializationdatatypes/primitivesdeclaringvariablesfloating-pointtypesglobalvariablehexadecimalliteralsintegertypesliteralsuffixeslocalvariableOctalliteralssignedintegersunsignedintegers
Visualstudiocompilation