Sie sind auf Seite 1von 112

2/26/2015 C++ Frequently Questioned Answers

C++FrequentlyQuestionedAnswers
ThisisasinglepageversionofC++FQALite.C++isageneralpurposeprogramminglanguage,notnecessarilysuitablefor
yourspecialpurpose.FQAstandsfor"frequentlyquestionedanswers".ThisFQAiscalled"lite"becauseitquestionsthe
answersfoundinC++FAQLite.

Thesinglepageversiondoesnotincludemost"metadata"sectionssuchastheFQAFAQ.

Tableofcontents
DefectiveC++alistofmajorlanguagedefects
C++Q&A,structuredsimilarlytoC++FAQLite,withlinkstotheoriginalFAQanswers
BigPictureIssues
Classesandobjects
Inlinefunctions
References
Constructors
Destructors
Assignmentoperators
Operatoroverloading
Friends
Input/outputvia<iostream>and<cstdio>
Freestoremanagement
Exceptions
Constcorrectness
Inheritancebasics
Inheritancevirtualfunctions
Inheritanceproperinheritanceandsubstitutability
Inheritanceabstractbaseclasses
Inheritancewhatyourmothernevertoldyou
Inheritancemultipleandvirtualinheritance
HowtomixCandC++
Pointerstomemberfunctions
Templates
FQAerrorsfoundbyreaders

DefectiveC++
ThispagesummarizesthemajordefectsoftheC++programminglanguage(listingallminorquirkswouldtakeeternity).To
befair,someoftheitemsbythemselvescouldbedesignchoices,notbugs.Forexample,aprogramminglanguagedoesn't
havetoprovidegarbagecollection.It'sthecombinationofthethingsthatmakesthemallproblematic.Forexample,thelack
ofgarbagecollectionmakesC++exceptionsandoperatoroverloadinginherentlydefective.Therefore,theproblemsarenot
listedintheorderof"importance"(whichissubjectiveanywaydifferentpeoplearehitthehardestbydifferentproblems).
Instead,mostdefectsarefollowedbyoneoftheircomplementarydefects,sothatwhenadefectcausesaproblem,thenext
defectinthelistmakesitworse.

Nocompiletimeencapsulation
Outstandinglycomplicatedgrammar
Nowaytolocatedefinitions
Noruntimeencapsulation
Nobinaryimplementationrules
Noreflection
Verycomplicatedtypesystem
Verycomplicatedtypebasedbindingrules
Defectiveoperatoroverloading
Defectiveexceptions
Duplicatefacilities
Nohighlevelbuiltintypes
Manualmemorymanagement
Defectivemetaprogrammingfacilities
Unhelpfulstandardlibrary
Defectiveinlining
http://yosefk.com/c++fqa/fqa.html 1/112
2/26/2015 C++ Frequently Questioned Answers
Implicitlycalled&generatedfunctions

Nocompiletimeencapsulation
InnaturallywrittenC++code,changingtheprivatemembersofaclassrequiresrecompilationofthecodeusingtheclass.
Whentheclassisusedtoinstantiatememberobjectsofotherclasses,theruleisofcourseappliedrecursively.

ThismakesC++interfacesveryunstableachangeinvisibleattheinterfacelevelstillrequirestorebuildthecallingcode,
whichcanbeveryproblematicwhenthatcodeisnotcontrolledbywhoevermakesthechange.SoshippingC++interfaces
tocustomerscanbeabadidea.

Well,atleastwhenallrelevantcodeiscontrolledbythesameteamofpeople,theonlyproblemisthefrequentrebuildsof
largepartsofit.Thiswouldn'tbetoobadbyitselfwithalmostanylanguage,butC++has...

Outstandinglycomplicatedgrammar
"Outstandingly"shouldbeinterpretedliterally,becauseallpopularlanguageshavecontextfree(or"nearly"contextfree)
grammars,whileC++hasundecidablegrammar.Ifyoulikecompilersandparsers,youprobablyknowwhatthismeans.If
you'renotintothiskindofthing,there'sasimpleexampleshowingtheproblemwithparsingC++:isAA BB(CC);anobject
definitionorafunctiondeclaration?Itturnsoutthattheanswerdependsheavilyonthecodebeforethestatementthe
"context".Thisshows(onanintuitivelevel)thattheC++grammarisquitecontextsensitive.

Inpractice,thismeansthreethings.First,C++compilesslowly(thecomplexitytakestimetodealwith).Second,whenit
doesn'tcompile,theerrormessagesarefrequentlyincomprehensible(thesmallesterrorwhichahumanreaderwouldn't
noticecompletelyconfusesthecompiler).Andthree,parsingC++rightisveryhard,sodifferentcompilerswillinterpretit
differently,andtoolslikedebuggersandIDEsperiodicallygetawfullyconfused.

Andslowcompilationinteractsbadlywithfrequentrecompilation.Thelatteriscausedbythelackofencapsulation
mentionedabove,andtheproblemisamplifiedbythefactthatC++has...

Nowaytolocatedefinitions
OK,sobeforewecanparseAA BB(CC);,weneedtofindoutwhetherCCisdefinedasanobjectoratype.Solet'slocatethe
definitionofCCandmoveon,right?

Thiswouldworkinmostmodernlanguages,inwhichCCiseitherdefinedinthesamemodule(sowe'vealreadycompiledit),
oritisimportedfromanothermodule(soeitherwe'vealreadycompiledit,too,orthismustbethefirsttimewebumpinto
thatmodulesolet'scompileitnow,once,butofcoursenotthenexttimewe'llneedit).Sotocompileaprogram,weneed
tocompileeachmodule,once,nomatterhowmanytimeseachmoduleisused.

InC++,thingsaredifferenttherearenomodules.Therearefiles,eachofwhichcancontainmanydifferentdefinitionsor
justsmallpartsofdefinitions,andthere'snowaytotellinwhichfilesCCisdefined,orwhichfilesmustbeparsedinorderto
"understand"itsdefinition.SowhoisresponsibletoarrangeallthosefilesintoasensiblestringofC++code?You,of
course!Ineachcompiledfile,you#includeabunchofheaderfiles(whichthemselvesincludeotherfiles)the#include
directivebasicallyissuesacopyandpasteoperationtotheCpreprocessor,inheritedbyC++withoutchanges.Thecompiler
thenparsestheresultofallthosecopyandpasteoperations.Sotocompileaprogram,weneedtocompileeachfilethe
numberoftimesitisusedinotherfiles.

Thiscausestwoproblems.First,itmultipliesthelongtimeittakestocompileC++codebythenumberoftimesit'susedina
program.Second,theonlywaytofigureoutwhatshouldberecompiledafterachangetothecodeistocheckwhichofthe
#includefileshavebeenchangedsincethelastbuild.Thesetoffilestorebuildgeneratedbythisinspectionisusuallya
supersetofthefilesthatreallymustberecompiledaccordingtotheC++rulesofdependenciesbetweendefinitions.That's
becausemostfiles#includedefinitionstheydon'treallyneed,sincepeoplecan'tspendalltheirtimeremovingredundant
inclusions.

Somecompilerssupport"precompiledheaders"savingtheresultoftheparsingof"popular"headerfilestosomebinaryfile
andquicklyloadingitinsteadofrecompilingfromscratch.However,thisonlyworkswellwithdefinitionsthatalmostnever
change,typicallythirdpartylibraries.

Andnowthatyou'vewaitedallthattimeuntilyourcodebaserecompiles,it'stimetorunandtesttheprogram,whichiswhen
thenextproblemkicksin.

Noruntimeencapsulation
http://yosefk.com/c++fqa/fqa.html 2/112
2/26/2015 C++ Frequently Questioned Answers
Programminglanguageshaverulesdefining"valid"programsforexample,avalidprogramshouldn'tdividebyzeroor
accessthe7thelementofanarrayoflength5.Avalidprogramisn'tnecessarilycorrect(forexample,itcandeleteafile
whenallyouaskedwastomoveit).However,aninvalidprogramisnecessarilyincorrect(thereisno7thelementinthe5
elementarray).Thequestionis,whathappenswhenaninvalidprogramdemonstratesitsinvaliditybyperforminga
meaninglessoperation?

Iftheanswerissomethinglike"anexceptionisraised",yourprogramrunsinamanagedenvironment.Iftheansweris
"anythingcanhappen",yourprogramrunssomewhereelse.Inparticular,CandC++arenotdesignedtoruninmanaged
environments(thinkaboutpointercasts),andwhileintheorytheycouldrunthere,inpracticeallofthemrunelsewhere.

SowhathappensinaC++programwiththe5elementarray?Mostfrequently,youaccesssomethingattheaddressthat
wouldcontainthe7thelement,butsincethereisn'tany,itcontainssomethingelse,whichjusthappenstobelocatedthere.
Sometimesyoucantellfromthesourcecodewhatthatis,andsometimesyoucan't.Anyway,you'rereallyluckyifthe
programcrashesbecauseifitkeepsrunning,you'llhavehardtimeunderstandingwhyitendsupcrashingormisbehaving
later.Ifitdoesn'tscareyou(youdebuggedacoupleofbufferoverflowsandfeelconfident),waituntilyougettomany
megabytesofmachinecodeandmanymonthsofexecutiontime.That'swhentherealfunstarts.

Now,theabilityofapieceofcodetomodifyarandomobjectwheninfactittriestoaccessanunrelatedarrayindicatesthat
C++hasnoruntimeencapsulation.Sinceitdoesn'thavecompiletimeencapsulation,either,onecanwonderwhyitcalls
itselfobjectoriented.Twopossibleanswersarewarpedperspectiveandmarketing(thesearen'tmutuallyexclusive).

Butifweleavetheclaimsaboutbeingobjectorientedaside,thefactthatalanguagerunsinunmanagedenvironmentscan't
reallybecalleda"bug".That'sbecausemanagedenvironmentscheckthingsatruntimetopreventillegaloperations,which
translatestoacertain(thoughfrequentlyoverestimated)performancepenalty.Sowhenperformanceisn'tthatimportant,a
managedenvironmentisthewaytogo.Butwhenit'scritical,youjusthavetodealwiththedifficultiesindebugging.
However,C++(comparedtoC,forexample)makesthatmuchharderthatitalreadyhastobe,becausethereare...

Nobinaryimplementationrules
Whenaninvalidprogramfinallycrashes(orentersaninfiniteloop,orgoestosleepforever),whatyou'releftwithisbasically
thebinarysnapshotofitsstate(acommonnameforitisa"coredump").Youhavetomakesenseofitinordertofindthe
bug.Sometimesadebuggerwillshowyouthecallstackatthepointofcrashfrequentlythatinformationisoverwrittenby
garbage.Otherthingswhichcanhelpthedebuggerfigurethingsoutmaybeoverwritten,too.

Now,figuringoutthemeaningofpartiallycorruptedmemorysnapshotsisdefinitelynotthemostpleasantwaytospend
one'stime.Butwithunmanagedenvironmentsyouhavetodoitanditcanbedone,ifyouknowhowyoursourcecodemaps
tobinaryobjectsandcode.ToobadthatwithC++,there'satonoftheserulesandeachcompilerusesdifferentones.Think
aboutexceptionhandlingorvariouskindsofinheritanceorvirtualfunctionsorthelayoutofstandardlibrarycontainers.InC,
there'snostandardbinarylanguageimplementationrules,either,butit'sanorderofmagnitudesimplerandinpractice
compilersusethesamerules.AnotherreasonmakingC++codehardtodebugistheabovementionedcomplicated
grammar,sincedebuggersfrequentlycan'tdealwithmanylanguagefeatures(placebreakpointsintemplates,parsepointer
castingcommandsindatadisplaywindows,etc.).

ThelackofastandardABI(applicationbinaryinterface)hasanotherconsequenceitmakesshippingC++interfacesto
otherteams/customersimpracticalsincetheusercodewon'tworkunlessit'scompiledwiththesametoolsandbuild
options.We'vealreadyseenanothersourceofthisproblemtheinstabilityofbinaryinterfacesduetothelackofcompile
timeencapsulation.

ThetwoproblemswithdebuggingC++codeandwithusingC++interfacesdon'tshowupuntilyourprojectgrows
complicatedintermsofcodeand/orhumaninteractions,thatis,untilit'stoolate.Butwait,couldn'tyoudealwithboth
problemsprogrammatically?YoucouldgenerateCorotherwrappersforC++interfacesandwriteprogramsautomatically
shovelingthroughcoredumpsanddecipheringthenoncorruptedparts,usingsomethingcalledreflection.Well,actually,
youcouldn't,notinareasonableamountoftimethere's...

Noreflection
Itisimpossibletoprogrammaticallyiterateoverthemethodsortheattributesorthebaseclassesofaclassinaportable
waydefinedbytheC++standard.Likewise,itisimpossibletoprogrammaticallydeterminethetypeofanobject(for
dynamicallyallocatedobjects,thiscanbejustifiedtoanextentbyperformancepenaltiesofRTTI,butnotforstatically
allocatedglobals,andifyoucouldstartattheglobals,youcoulddecipherlotsofmemorypointedbythem).Featuresofthis
sortwhenaprogramcanaccessthestructureofprograms,inparticular,itsownstructurearecollectivelycalledreflection,
andC++doesn'thaveit.

Asmentionedabove,thismakesgeneratingwrappersforC++classesandshovelingthroughmemorysnapshotsapain,but
that'sasmallfractionofthethingsC++programmersaremissingduetothissingleissue.Wrapperscanbeusefulnotonly
http://yosefk.com/c++fqa/fqa.html 3/112
2/26/2015 C++ Frequently Questioned Answers
toworkaroundtheproblemofshippingC++interfacesyoucouldautomaticallyhandlethingslikeremoteprocedurecalls,
loggingmethodinvocations,etc.Averycommonapplicationofreflectionisserializationconvertingobjectstobyte
sequencesandviceversa.Withreflection,youcanhandleitforalltypesofobjectswiththesamecodeyoujustiterateover
theattributesofcompoundobjects,andonlyneedspecialcasesforthebasictypes.InC++,youmustmaintainserialization
relatedcodeand/ordatastructuresforeveryclassinvolved.

Butperhapswecoulddealwiththisproblemprogrammaticallythen?Afterall,debuggersdomanagetodisplayobjects
somehowthedebuginformation,emittedintheformatsupportedbyyourtoolchain,describesthemembersofclassesand
theiroffsetsfromtheobjectbasepointerandallthatsortofmetadata.Ifwe'restuckwithC++,perhapswecouldparsethis
informationandthushavenonstandard,butworkingreflection?Severalthingsmakethisprettyhardnotallcompilerscan
producedebuginformationandoptimizetheprogramaggressivelyenoughforareleasebuild,notalldebuginformation
formatsaredocumented,andtheninC++,wehavea...

Verycomplicatedtypesystem
InC++,wehavestandardandcompilerspecificbuiltintypes,structures,enumerations,unions,classeswithsingle,
multiple,virtualandnonvirtualinheritance,constandvolatilequalifiers,pointers,referencesandarrays,typedefs,global
andmemberfunctionsandfunctionpointers,andtemplates,whichcanhavespecializationson(again)types(orintegral
constants),andyoucan"partiallyspecialize"templatesbypatternmatchingtheirtypestructure(forexample,havea
specializationforstd::vector<MyRetardedTemplate<T> >forarbitraryvaluesofT),andeachtemplatecanhavebaseclasses
(inparticular,itcanbederivedfromitsowninstantiationsrecursively,whichisawellknownpracticedocumentedinbooks),
andinnertypedefs,and...Wehavelotsofkindsoftypes.

Naturally,representingthetypesusedinaC++program,say,indebuginformation,isnotaneasytask.Atrivialyet
annoyingmanifestationofthisproblemistheexpansionoftypedefsdonebydebuggerswhentheyshowobjects(and
compilerswhentheyproduceerrormessagesanotherreasonwhythesearesocryptic).Youmaythinkit'sa
StringToStringMap,butonlyuntilthetoolsenlightenyouit'sactuallymoreofa...

// don't read this, it's impossible. just count the lines


std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> >
>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > > > >

Butwait,there'smore!C++supportsawidevarietyofexplicitandimplicittypeconversions,sonowwehaveanicesetof
rulesdescribingthecartesianproductofallthosetypes,specifically,howconversionshouldbehandledforeachpairof
types.Forexample,ifyourfunctionacceptsconst std::vector<const char*>&(whichissupposedtomean"areferenceto
animmutablevectorofpointerstoimmutablebuiltinstrings"),andIhaveastd::vector<char*>object("amutablevectorof
mutablebuiltinstrings"),thenIcan'tpassittoyourfunctionbecausethetypesaren'tconvertible.Youhavetoadmitthatit
doesn'tmakeanysense,becauseyourfunctionguaranteesthatitwon'tchangeanything,andIguaranteethatIdon'teven
mindhavinganythingchanged,andstilltheC++typesystemgetsinthewayandtheonlysaneworkaroundistocopythe
vector.Andthisisanextremelysimpleexamplenovirtualinheritance,nouserdefinedconversionoperators,etc.

Butconversionrulesbythemselvesarestillnottheworstproblemwiththecomplicatedtypesystem.Theworstproblemis
the...

Verycomplicatedtypebasedbindingrules
TypeslieatthecoreoftheC++bindingrules."Binding"means"findingtheprogramentitycorrespondingtoaname
mentionedinthecode".WhentheC++compilercompilessomethinglikef(a,b)(orevena+b),itreliesontheargument
typestofigureoutwhichversionoff(oroperator+)tocall.Thisincludesoverloadresolution(isitf(int,int)or
f(int,double)?),thehandlingoffunctiontemplatespecializations(isittemplate<class T> void f(vector<T>&,int)or
template<class T> void f(T,double)?),andtheargumentdependentlookup(ADL)inordertofigureoutthenamespace(is
itA::forB::f?).

Whenthecompiler"succeeds"(translatessourcecodetoobjectcode),itdoesn'tmeanthatyouareequallysuccessful(that
is,youthinka+bcalledwhatthecompilerthoughtitcalled).Whenthecompiler"fails"(translatessourcecodetoerror
messages),mosthumansalsofail(tounderstandtheseerrormessagesmultiplescreenslistingallavailableoverloadsof
thingslikeoperator<<arelessthanhelpful).Bytheway,theC++FAQhasveryfewitemsrelatedtotheunbelievably
complicatedstaticbinding,likeoverloadresolutionorADLortemplatespecialization.Presumablypeoplegettoodepressed
toaskanyquestionsandsilentlygiveup.

Inshort,thecomplicatedtypesysteminteractsverybadlywithoverloadinghavingmultiplefunctionswiththesamename
andhavingthecompilerfigureoutwhichofthemtousebasedontheargumenttypes(don'tconfuseitwithoverriding
virtualfunctions,thoughveryfarfromperfect,dofollowrulesquitesanebyC++standards).Andprobablytheworstkindof
http://yosefk.com/c++fqa/fqa.html 4/112
2/26/2015 C++ Frequently Questioned Answers
overloadingis...

Defectiveoperatoroverloading
C++operatoroverloadinghasalltheproblemsofC++functionoverloading(incomprehensibleoverloadresolutionrules),
andthensome.Forexample,overloadedoperatorshavetoreturntheirresultsbyvaluenaivelyreturningreferencesto
objectsallocatedwithnewwouldcausetemporaryobjectsto"leak"whencodelikea+b+cisevaluated.That'sbecauseC++
doesn'thavegarbagecollection,sincethat,folks,isinefficient.Muchbettertohaveyourcodecopymassivetemporary
objectsandhopetohavethemoptimizedoutbyourfriendtheclevercompiler.Which,ofcourse,won'thappenanytime
soon.

LikeseveralotherfeaturesinC++,operatoroverloadingisnotnecessarilyabadthingbyitselfitjusthappenstointeract
reallybadlywithotherthingsC++.Thelackofautomaticmemorymanagementisonethingmakingoperatoroverloading
lessthanuseful.Anothersuchthingis...

Defectiveexceptions
Considererrorhandlinginanoverloadedoperatororaconstructor.Youcan'tusethereturnvalue,andsetting/readingerror
flagsmaybequitecumbersome.Howaboutthrowinganexception?

ThiscouldbeagoodideainsomecasesifC++exceptionswereanygood.Theyaren't,andcan'tbeasusual,becauseof
anotherC++"feature",theohsoefficientmanualmemorymanagement.Ifweuseexceptions,wehavetowriteexception
safecodecodewhichfreesallresourceswhenthecontrolistransferredfromthepointoffailure(throw)tothepointwhere
expliciterrorhandlingisdone(catch).Andthevastmajorityof"resources"happenstobememory,whichismanaged
manuallyinC++.Tosolvethis,youaresupposedtouseRAII,meaningthatallpointershavetobe"smart"(bewrappedin
classesfreeingthememoryinthedestructor,andthenyouhavetodesigntheircopyingsemantics,and...).Exceptionsafe
C++codeisalmostinfeasibletoachieveinanontrivialprogram.

Ofcourse,C++exceptionshaveotherflaws,followingfromstillotherC++misfeatures.Forexample,theabovementioned
lackofreflectioninthespecialcaseofexceptionsmeansthatwhenyoucatchanexception,youcan'tgetthecallstack
describingthecontextwhereitwasthrown.Thismeansthatdebuggingillegalpointerdereferencingmaybeeasierthan
figuringoutwhyanexceptionwasthrown,sinceadebuggerwilllistthecallstackinmanycasesoftheformer.

Atthebottomline,throw/catchareaboutasusefulaslongjmp/setjmp(BTW,theformertypicallyrunsfaster,butit'smere
existencemakestherestofthecoderunslower,whichisalmostneveracknowledgedbyC++aficionados).Sowehavetwo
features,eachwithitsownflaws,andnointeroperabilitybetweenthem.ThisistrueforthevastmajorityofC++features
mostare...

Duplicatefacilities
IfyouneedanarrayinC++,youcanuseaClikeT arr[]oraC++std::vector<T>oranyofthearrayclasseswrittenbefore
std::vectorappearedintheC++standard.Ifyouneedastring,usechar*orstd::stringoranyoftheprestandardstring
classes.Ifyouneedtotaketheaddressofanobject,youcanuseaClikepointer,T*,oraC++reference,T&.Ifyouneedto
initializeanobject,useClikeaggregateinitializationorC++constructors.Ifyouneedtoprintsomething,youcanuseaC
likeprintfcalloraC++iostreamcall.Ifyouneedtogeneratemanysimilardefinitionswithsomeparametersspecifyingthe
differencesbetweenthem,youcanuseClikemacrosorC++templates.Andsoon.

Ofcourseyoucandothesamethinginmanywaysinalmostanylanguage.ButtheC++featureduplicationisquitespecial.
First,themanywaystodothesamethingareusuallynotpurelysyntacticoptionsdirectlysupportedbythecompileryou
cancomputea+bwitha-b*-1,butthat'sdifferentfromhavingT*andT&inthesamelanguage.Second,youprobablynoticed
apatternC++addsfeaturesduplicatingfunctionalityalreadyinC.Thisisbadbyitself,becausethefeaturesdon't
interoperatewell(youcan'tprintftoaniostreamandviceversa,codemixingstd::stringandchar*islitteredwithcasts
andcallstostd::string::c_str,etc.).ThisismadeevenworsebytheprettyamazingfactthatthenewC++featuresare
actuallyinferiortotheoldConesinmanyaspects.

AndthebestpartisthatC++devoteesdaretorefertotheCfeaturesasevil,andfrequentlywillactuallyresorttofinger
pointingandnamecallingwhensomeoneusestheminC++code(nottomentionusingplainC)!Andatthesametimethey
(falsely)claimthatC++iscompatiblewithCandit'soneofitsstrengths(why,ifCissoevil?).TherealreasontoleavetheC
syntaxinC++wasofcoursemarketingthere'sabsolutelyNOtechnicalreasontoparseClikesyntaxinordertoworkwith
existingCcodesincethatcodecanbecompiledseparately.Forexample,mixingCandtheDprogramminglanguageisn't
harderthanmixingCandC++.DisagoodexamplesinceitsstatedgoalsaresimilartothoseofC++,butalmostallother
popularlanguageshavewaystoworkwithCcode.

SoIMOallthatoldsyntaxwaskeptforstrictlycommercialpurposestomarketthelanguagetonontechnicalmanagersor
http://yosefk.com/c++fqa/fqa.html 5/112
2/26/2015 C++ Frequently Questioned Answers
programmerswhoshouldhaveknownbetteranddidn'tunderstandthedifferencebetween"syntax"and"compatibilitywith
existingcode"andsimplyaskedwhethertheoldcodewillcompilewiththisnewcompiler.Ormaybetheythoughtitwouldbe
easiertolearnapileofnewsyntaxwhenyoualsohavethe(smaller)pileofoldsyntaxthanwhenyouhavejustthenew
syntax.Eitherway,C++gotwidespreadbyexploitingmisconceptions.

Well,itdoesn'tmatteranymorewhytheykepttheoldstuff.Whatmattersisthatthenewstuffisn'treallynew,eitherit's
obsessivelybuiltinwaysexposingtheCinfrastructureunderneathit.Andthatispurelyawrongdesigndecision,made
withoutanaxetogrind.Forexample,inC++there's...

Nohighlevelbuiltintypes
Cisaprettylowlevellanguage.Itsatomictypesaresupposedtofitintomachineregisters(usuallyone,sometimestwoof
them).Thecompoundtypesaredesignedtooccupyaflatchunkofmemorywithofasizeknownatcompiletime.

Thisdesignhasitsvirtues.Itmakesitrelativelyeasytoestimatetheperformance&resourceconsumptionofcode.And
whenyouhavehardtocatchlowlevelbugs,whichsoonerorlaterhappensinunmanagedenvironments,havingarelatively
simplecorrespondencebetweensourcecodedefinitionsandmachinememoryhelpstodebugtheproblem.However,ina
highlevellanguage,whichissupposedtobeusedwhenthedevelopmenttimecost/executiontimecostratioishigh,you
needthingslikeresizablearrays,keyvaluemappings,integersthatdon'toverflowandothersuchgadgets.Emulatingthese
inalowlevellanguageispossible,butisinvariablypainfulsincethetoolsdon'tunderstandthecoretypesofyourprogram.

C++doesn'taddanybuiltintypestoC(correction).Allhigherleveltypesmustbeimplementedasuserdefinedclassesand
templates,andthisiswhenthedefectsofC++classesandtemplatesmanifestthemselvesintheirfullglory.Thelackof
syntacticsupportforhigherleveltypes(youcan'tinitializestd::vectorwith{1,2,3}orinitializeanstd::mapwithsomething
like{"a":1,"b":2}orhavelargeintegerconstantslike3453485348545459347376)isthesmallpartoftheproblem.Cryptic
multilineormultiscreencompilererrormessages,debuggersthatcan'tdisplaythestandardC++typesandslowbuild
timesunheardofanywhereoutsideoftheC++worldarethelargerpartoftheproblem.Forexample,here'sasimplepiece
ofcodeusingtheC++standardlibraryfollowedbyanerrormessageproducedfromitbygcc4.2.0.Quiz:what'sthe
problem?
// the code
typedef std::map<std::string,std::string> StringToStringMap;
void print(const StringToStringMap& dict) {
for(StringToStringMap::iterator p=dict.begin(); p!=dict.end(); ++p) {
std::cout << p->first << " -> " << p->second << std::endl;
}
}
// the error message
test.cpp: In function 'void print(const StringToStringMap&)':
test.cpp:8: error: conversion from
'std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >' to non-scalar type
'std::_Rb_tree_iterator<std::pair<const std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >' requested

Thedecisiontoavoidnewbuiltintypesyieldsotherproblems,suchastheabilitytothrowanything,butwithouttheabilityto
catchitlater.class Exception,abuiltinbaseclassforallexceptionclassestreatedspeciallybythecompiler,couldsolve
thisproblemwithC++exceptions(butnotothers).However,themostcostlyproblemwithhavingnonewhighlevelbuiltin
typesisprobablythelackofeasytousecontainers.Buttohavethose,weneedmorethanjustnewbuiltintypesand
syntaxintheC++compiler.Complicateddatastructurescan'tbemanipulatedeasilywhenyouonlyhave...

Manualmemorymanagement
Similarlytolowlevelbuiltintypes,C++manualmemorymanagementisinheritedfromCwithoutchanges(butwiththe
mandatoryadditionofduplicatesyntaxnew/delete,whichnormallycallmalloc/freebutdon'thavetodothat,andofcourse
canbeoverloaded).

Similarlytothecasewithlowlevelbuiltintypes,whatmakessenseforalowlevellanguagedoesn'tworkwhenyouadd
higherlevelfeatures.Manualmemorymanagementisincompatiblewithfeaturessuchasexceptions&operator
overloading,andmakesworkingwithnontrivialdatastructuresveryhard,sinceyouhavetoworryaboutthelifecyclesof
objectssotheywon'tleakordiewhilesomeonestillneedsthem.

Themostcommonsolutioniscopyingsinceit'sdangeroustopointtoanobjectwhichcandiebeforewe'redonewithit,
makeyourselfacopyandbecomean"owner"ofthatcopytocontrolitslifecycle.An"owner"isaC++conceptnot
representedinitssyntaxan"owner"istheobjectthatisresponsibletodeallocateadynamicallyallocatedchunkofmemory
orsomeotherresource.ThestandardpracticeinC++istoassigneach"resource"(afancynameformemory,mostofthe
time)toanownerobject,whichissupposedtopreventresourceleaks.Whatitdoesn'tpreventisaccesstodeadobjectswe
http://yosefk.com/c++fqa/fqa.html 6/112
2/26/2015 C++ Frequently Questioned Answers
havecopyingforthat.Whichisslowanddoesn'tworkwhenyouneedmanypointerstothesameobject(forexample,when
youwantothermodulestoseeyourmodificationstotheobject).

Analternativesolutiontocopyingisusing"smart"pointerclasses,whichcouldemulateautomaticmemorymanagementby
maintainingreferencecountsorwhatnot.Toimplementthepointerclassesforthemanydifferenttypesinyourprogram,
you'reencouragedtouse...

Defectivemetaprogrammingfacilities
Thereareroughlytwokindsofmetaprogramming:codethatgeneratesothercodeandcodethatprocessesothercode.The
secondkindispracticallyimpossibletodowithC++codeyoucan'treliablyprocesssourcecodeduetotheextremely
complicatedgrammarandyoucan'tportablyprocesscompiledcodebecausethere'snoreflection.Sothissectionisabout
thefirstkindcodegeneration.

YoucangenerateC++codefromwithinaC++programusingCmacrosandC++templates.Ifyouusemacros,yourisk
gettingclubbedtodeathbyC++fanatics.Theirirrationalbehaviorleftaside,thesepeopledohaveapointCmacrosare
prettylame.Toobadtemplatesareprobablyevenworse.Theyarelimitedinwaysmacrosaren't(however,theoppositeis
alsotrue).Theycompileforever.Beingtheonlywaytodometaprogramming,theyareroutinelyabusedtodothingsthey
weren'tdesignedfor.Andtheyarearats'nestofbizarresyntacticproblems.

Thatwouldn'tnecessarilybesobadifC++didn'trelyonmetaprogrammingfordoingessentialprogrammingtasks.One
reasonC++hastodosoisthatinC++,thecommonpracticeistousestaticbinding(overloadresolution,etc.)toimplement
polymorphism,notdynamicbinding.Soyoucan'ttakeanarbitraryobjectatruntimeandprintit,butinmanyprogramsyou
cantakeanarbitrarytypeatcompiletimeandprintobjectsofthistype.Here'sonecommon(andbroken)applicationof
metaprogrammingtheultimatepurposeistobeabletoprintarbitraryobjectatruntime:
// an abstract base class wrapping objects of arbitrary types.
// there can be several such classes in one large project
struct Obj {
virtual void print(std::ostream&) const = 0;
};
template<class T> struct ObjImpl : Obj {
T wrapped;
virtual void print(std::ostream& out) const { out << wrapped; }
};
// now we can wrap int objects with ObjImpl<int> and string objects
// with ObjImpl<std::string>, store them in the same collection of Obj*
// and print the entire collection using dynamic polymorphism:
void print_them(const std::vector<Obj*>& objects) {
for(int i=0; i<(int)objects.size(); ++i) {
objects[i]->print(std::cout); // prints wrapped ints, strings, etc.
std::cout << std::endl;
}
}

Typicallythereare10morelayersofsyntaxinvolved,butyougettheidea.Thissortofcodedoesn'treallyworkbecauseit
requiresallrelevantoverloadsofoperator<<tobevisiblebeforethepointwhereObjImplisdefined,andthatdoesn'thappen
unlessyouroutinelysortyour#includedirectivesaccordingtothatrule.Somecompilerswillcompilethecodecorrectlywith
theruleviolated,somewillcomplain,somewillsilentlygeneratewrongcode.

ButthemostbasicreasontorelyonthepoorC++metaprogrammingfeaturesforeverydaytasksistheabovementioned
ideologicaldecisiontoavoidaddinghighlevelbuiltintypes.Forexample,templatesareatthecoreofthe...

Unhelpfulstandardlibrary
MostthingsdefinedbytheC++standardlibraryaretemplates,andrelativelysophisticatedones,causingtheuserstodeal
withquitesophisticatedmanifestationsoftheproblemswithtemplates,discussedabove.Inparticular,aspecialprogram
calledSTLFiltexistsfordecryptingtheerrormessagesrelatedtotheC++standardlibrary.Toobaditdoesn'tpatchthe
debuginformationinasimilarway.

Anotherproblemwiththestandardlibraryisallthefunctionalitythat'snotthere.Alargepartofthelibraryduplicatesthe
functionalityfromtheCstandardlibrary(whichisitselfavailabletoC++programs,too).Themainnewthingiscontainers
("algorithms"likemaxandadjacent_differencedon'tcountas"functionality"inmybook).Thestandardlibrarydoesn't
supportlistingdirectories,openingGUIwindowsornetworksockets.Youmaythinkthat'sbecausethesethingsarenon
portable.Well,thestandardlibrarydoesn'thavematricesorregularexpressions,either.

Andwhenyouusethestandardlibraryinyourcode,onereasonitcompilesslowlytoalargebinaryimageisthatthelibrary
extensivelyusesthe...

http://yosefk.com/c++fqa/fqa.html 7/112
2/26/2015 C++ Frequently Questioned Answers

Defectiveinlining
First,let'sdefinetheterms.

"Inlining"inthecontextofcompilersreferstoatechniqueforimplementingfunctioncalls(insteadofgeneratingasequence
callingtheimplementationofthefunction,thecompilerintegratesthatimplementationatthepointwherethecallismade).
"Inlining"inthecontextofC++referstoawaytodefinefunctionsinordertoenable(asopposedto"force")such
implementationofthecallstothefunction(thedecisionwhethertoactuallyusetheopportunityismadebythecompiler).

Now,themajorproblemwiththisC++waytoenableinliningisthatyouhavetoplacethedefinitionofthefunctioninheader
files,andhaveitrecompiledoverandoveragainfromsource.Thisdoesn'thavetobethatwaytherecompilationfrom
sourcecanbeavoidedbyhavinghigherlevelobjectfileformats(thewayit'sdoneinLLVMandgccstartingfromversion4).
Thisapproachlinktimeinliningisoneaspectof"wholeprogramoptimization"supportedbymoderncompilers.Butthe
recompilationfromsourcecouldalsobeavoidedinsimplerwaysifC++hadawaytolocatedefinitionsinsteadof
recompilingthem,which,aswe'veseen,ithasn't.

Thecrudesupportforinlining,designedwithatraditionalimplementationofaCtoolchaininmind,wouldn'tbeasbadifit
wasn'tusedallthetime.Peopledefinelargefunctionsinlinefortworeasons.Someofthem"care"(emotionally)about
performance,butneveractuallymeasureit,andsomeonetoldthemthatinliningspeedsthingsup,andforgottotellthem
howitcanslowthemdown.Anotherreasonisthatit'ssimplyannoyingtodefinefunctionsnoninline,sincethatway,you
placethefullfunctiondefinitionina.cppfileanditsprototypeina.hfile.Soyouwritetheprototypetwice,withsmall
changes(forexample,ifaclassmethodreturnsanobjectofatypeitselfdefinedintheclass,you'llneedanextra
namespacequalificationinthe.cppfilesinceyou'renowoutsideofthenamespaceoftheclass).Mucheasiertojusthave
thebodywrittenrightinthe.hfile,makingthecodecompilemoreslowlyandrecompilemorefrequently(changingthe
functionbodywilltriggerarecompilation).

Andyoudon'tevenneedtoactuallywriteanyinlinefunctionstogetmostoftheirbenefits!Alargesubsetoftheinline
functionsofaprogramare...

Implicitlycalled&generatedfunctions
Here'sacommon"designpattern"inC++code.Youhaveahugeclass.Sometimesthere'sasinglepseudoglobalobjectof
thisclass.Inthatcase,yougetallthedrawbacksofglobalvariablesbecauseeverybodyhasapointertothethingand
modifiesitandexpectsotherstoseethechanges.Butyougetnobenefitsofglobalvariablessincethethingisallocatedon
thestackandwhenyourprogramcrasheswithabufferoverflow,youcan'tfindtheobjectinadebugger.Andatothertimes
therearemanyoftheseobjects,typicallykeptinapseudoglobalcollection.

Anyway,thishugeclasshasnoconstructors,nodestructorandnooperator=.Ofcoursepeoplecreateanddestroythe
objects,andsometimesevenassigntothem.Howisthishandledbythecompiler?

Thisishandledbythecompilerbygeneratingagiganticpileofcodeatthepointwhereitwouldcalltheuserdefined
functionswithmagicnames(suchasoperator=)iftherewereany.Whenyoucrashsomewhereatthatpoint,yougettosee
kilobytesofassemblycodeinthedebugger,allgeneratedfromthesamesourcecodeline.Youcanthentryandfigureout
whichvariabledidn'tlikebeingassignedto,byguessingwheretheclassmemberoffsetsareintheassemblylistingand
lookingforsymbolicnamesofthememberscorrespondingtothem.Oryoucantryandguesswhoforgotallaboutthefact
thattheseobjectswereassignedtousingthe"default"operator=andaddedsomethinglikebuiltinpointermemberstothe
class.Becausethatwouldn'twork,andcouldhavecausedtheproblem.

Implicitgenerationoffunctionsisproblematicbecauseitslowscompilationdown,inflatestheprogrambinariesandgetsin
thewaywhenyoudebug.Buttheproblemwithimplicitlycallingfunctions(whetherornottheywereimplicitlygenerated)is
arguablyevenworse.

Whenyouseecodelikea=f(b,c)(orevena=b+c,thankstooperatoroverloading),youdon'tknowwhethertheobjectsare
passedbyreferenceorbyvalue(see"informationhiding").Inthelattercase,theobjectsarecopiedwithimplicitlycalled
functionsintheformercase,that'spossible,too,ifimplicittypeconversionswereinvolved.Whichmeansthatyoudon't
reallyunderstandwhattheprogramdoesunlessyouknowtherelevantinformationabouttherelevantoverloadsandtypes.
Andbytheway,thefactthatyoucan'tseewhethertheobjectispassedbyreferenceorbyvalueatthepointofcallis
anotherexampleofimplicitstuffhappeninginC++.

Onemoreproblemwithautomaticallygeneratedfunctions(suchasconstructorsanddestructors)isthattheymustbe
regeneratedwhenyouaddprivatememberstoaclass,sochangingtheprivatepartsofaclasstriggersrecompilation...
Whichbringsusbacktosquare1.

BigPictureIssues
http://yosefk.com/c++fqa/fqa.html 8/112
2/26/2015 C++ Frequently Questioned Answers
ThispartdealswiththeBig(andsomewhatSad)Picture.

[6.1]IsC++apracticallanguage?
[6.2]IsC++aperfectlanguage?
[6.3]What'sthebigdealwithOO?
[6.4]What'sthebigdealwithgenericprogramming?
[6.5]IsC++betterthanAda?(orVisualBasic,C,FORTRAN,Pascal,Smalltalk,oranyotherlanguage?)
[6.6]WhousesC++?
[6.7]HowlongdoesittaketolearnOO/C++?
[6.8]WhataresomefeaturesofC++fromabusinessperspective?
[6.9]Arevirtualfunctions(dynamicbinding)centraltoOO/C++?
[6.10]I'mfromMissouri.Canyougivemeasimplereasonwhyvirtualfunctions(dynamicbinding)makeabig
difference?
[6.11]IsC++backwardcompatiblewithANSI/ISOC?
[6.12]IsC++standardized?
[6.13]WherecanIgetacopyoftheANSI/ISOC++standard?
[6.14]Whataresome"interviewquestions"Icouldaskthatwouldletmeknowifcandidatesreallyknowtheirstuff?
[6.15]WhatdoestheFAQmeanby"suchandsuchisevil"?
[6.16]WillIsometimesuseanysocalled"evil"constructs?
[6.17]Isitimportanttoknowthetechnicaldefinitionof"goodOO"?Of"goodclassdesign"?
[6.18]WhatshouldItellpeoplewhocomplainthattheword"FAQ"ismisleading,thatitemphasizesthequestions
ratherthantheanswers,andthatweshouldallstartusingadifferentacronym?

[6.1]IsC++apracticallanguage?
FAQ:Surenotperfect,butmatureandwellsupported,whichisgoodforbusiness.

FQA:C++isnot"mature"inthesensethatdifferentcompilerswillinterpretitdifferently,andC++modulesbuiltbydifferent
vendorswillnotworkwitheachother.C++isnot"wellsupported"inthesensethatdevelopmenttoolsforC++lackfeatures
andareunreliablecomparedtootherlanguages.Thesethingsmakeoneask"AmIthefirstonetryingtodothis?"allthe
time.

Thissituationisnotlikelytochange,becauseitfollowsfromtheC++definition.C++isverycomplicatedforprograms(or
people)tounderstand.C++specificationleavesoutmostaspectscrucialforinteroperability,suchasmodulesandcalling
conventions.C++hasahugeinstalledbase,andsincesolvingtheseproblemsbackwardcompatiblyisimpossible,they
won'tbesolved.

[6.2]IsC++aperfectlanguage?
FAQ:No,anditshouldn'tbe,itshouldbepractical,which,aswe'vejustseen,itis.Perfectisforacademy,practicalisfor
business.

FQA:Nolanguageis"perfect"becauseourrequirementsfroma"perfect"languageareinconsistentwitheachother.So
insteadofperfection,goodlanguagesprovideconsistencyandusability.Thiscanbecalled"practical"fromthepointofview
oflanguageusers.

C++isdifferentit'sdesignedforperfection.Whereotherlanguagesgiveyouafeature,C++givesyoumetafeatures.
Insteadofbuiltinstringsandvectors,itgivesyoutemplates.Insteadofgarbagecollection,itgivesyousmartpointers.This
way,youcan(theoretically)implementyourown"perfect"(mostefficientandgeneric)strings.Inpractice,thisturnsintoa
nightmaresincemanydifferentkindsofstrings,smartpointers,etc.,eachperfectinitsownway,willnotworkwitheach
other.C++sacrificesusabilityforperfection.

However,despitetheobsessionwithperfection,C++is"practical"fromalanguagedesigner'sperspectiveratherthanfrom
auser'spointofview.The"practical"thinginC++isthatit'sbasedonC.Thishelpedthelanguagegainpopularity.Thisis
alsothemainreasonforinconsistenciesinthelanguageambiguitiesinthegrammar(declaration/definition,type
name/objectname...),duplicationsoffunctionalityinthedifferentfeatures(pointers/references,constructors/aggregate
initialization,macros/constants/templates,files/namespaces...).C++sacrificesconsistencyforpopularity.This"practical"
approachhelpstoincreasethenumberofC++users,butitdoesn'thelpthoseuserstogettheirjobdone.

[6.3]What'sthebigdealwithOO?
FAQ:Objectorientedprogrammingisthebestknownwaytodevelopcomplexsystems.Itwasinventedbecausecustomers
keptdemandingincreasinglycomplexsystems.

http://yosefk.com/c++fqa/fqa.html 9/112
2/26/2015 C++ Frequently Questioned Answers
FQA:Objectorientedprogrammingisveryuseful.Foralotofthingsit'ssousefulyou'relikelytowantsupportforitbuiltinto
yourlanguage.Ofcoursenobodyknowshowtobuildcomplexsystemsinthegeneralcase(orinyourspecialcase).OOP
canhelp,otherthingscanhelp,butultimatelythereisnosimplewaytodealwithcomplexity.Whichisonlysurprisingifyou
thinkthatthereshouldexistareliableprocesstoproduceanythingpeoplearewillingtopayfor.Thelawsofbusinessare
powerful,thelawsofnaturearemorepowerful.

Mostkindsofbuiltinlanguagesupportforobjectorientedprogramming,includingnosuchsupport,havebigadvantages
overC++classes.ThesinglebiggestproblemwithC++classesisthatprivatemembersarewritteninheaderfiles,so
changingthemrequiresrecompilingthecodeusingthemforimportantpracticalpurposes,thismakesprivatemembersa
partoftheinterface.C++isbuiltsuchthatrecompilationisveryslow(anorderofmagnitudeslowerthanitiswithvirtually
anyotherlanguage),andclassesarebuilttomakerecompilationafrequentevent.

Fromabusinessperspective,thismeanstwothings:yourC++developersspendasignificantamountoftheirtimein
recompilationcycles,andC++interfacesprovidedtoyourcustomersorbyyourvendorswillcauseyoumajorheadaches
(whenversionsareupgraded,someofthecodewon'tberecompiledandsoftwarewillfailincreativeways).Luckily,C++
interfacesarehardtoprovide(effectivelyallpartiesmustusethesamecompilerwiththesamesettings),soquitetypically
C++moduleshaveinterfaceswritteninC.

[6.4]What'sthebigdealwithgenericprogramming?
FAQ:Genericprogrammingallowstocreatecomponentswhichareeasytouse,widelyapplicable(reusable)andefficient.
Usingthemmakesyourcodefasterandreducestheamountoferrors.Creatingthemisa"nonprocess"(apoetic
descriptionofsolvinghardproblemsfollowswakingupatnightandotherthingsprobablyquestionablefromthe"business
perspective"ofwhichtheFAQissofond).Mostpeoplecanusethem,butaren'tcutouttocreatetheirownonemustliketo
solvepuzzlesforthat.Butthesegenericcomponentsaresogenericthatyoucanprobablyfindanofftheshelfoneforyour
needs.

FQA:"Genericprogramming"inthecontextofC++referstotemplates.

Templatesarehardtouse(andnotonlydefine&implement)duetocrypticcompilererrormessages,extremelylong
compilationtimeandremarkablehostilitytosymbolicdebuggingbothcodebrowsinganddatainspection.Theusability
problemsarenotsolvedbyusingofftheshelfcomponents.

Templatesaremostlyapplicabletocontainersorsmartpointers,whichcancontainorpointtoalmostanything.Whenthe
constraintsontheinputarelesstrivial,mostofthetimeyoueitherdon'treallyneedpolymorphism,oryouarebetteroffwith
dynamicpolymorphism(forexample,thekindyougetwithC++virtualfunctions).That'sbecauseinmostcases,thebenefits
(suchasseparatecompilation)areworththeoverheadofdynamicbinding(whichisdwarfedbythecomplexityofthe
dispatchedoperationsthemselves).

Templatesareaformofcodegeneration,andhencetheydon'tmakecodefasterorslowercomparedtocodeyou'dwrite
manually.Theydotendtomakeitlargersincethecompilergeneratesthesamecodemanytimes.Althoughthereare
theoreticalwaystoavoidthis,youfindyourselfsolvingsomeoneelse'sproblem.Withthe"evil"Cmacrosyoucanatleast
controlwhentheyareexpanded.

Peoplewholiketosolvepuzzlesusuallypreferinterestingpuzzles.Withtemplates,thegreatestpuzzleiswhatonEarththe
codemeans(evencompilersfrequentlydisagree).Practicalpeopleavoidfiddlingwithproblemswhichnobodyactually
wantssolved,andtemplatesareonlyinterestinginsidetheworldofC++,nottherealworld.

[6.5]IsC++betterthanAda?(orVisualBasic,C,FORTRAN,Pascal,
Smalltalk,oranyotherlanguage?)
FAQ:Answeringthisquestionisnotveryhelpfulbecausebusinessconsiderationsdominatetechnicalconsiderations.
Specifically,availability(ofcompiletimeandruntimeenvironments,tools,developers)isthemostimportantconsideration.
Peoplewhodon'tgetthisaretechieweeniesendangeringtheiremployer'sinterests.

FQA:Answeringthisquestionisnotveryhelpfulbecausetherealquestioniswhatlanguageisbestforyourspecific
purposes.Thepurposesaredefinedbythebusinessconsiderations(whatseemsworthdoing)andbytechnical
considerations(whatseemspossibletodo).Inparticular,yourpurposesmaylimittheavailabilityofdevelopers,tools,etc.
Theseconstraintsarenecessarytomeet.

Onethingisalwaystrue:whereyoucanuseC++,youcanuseC.Inparticular,ifsomeonegaveyouC++interfaces,athin
layerofwrapperswillhidethem.UsingCinsteadofC++hasseveralpracticalbenefits:fasterdevelopmentcycle,reduced
complexity,bettersupportbytoolssuchasdebuggers,higherportabilityandinteroperability.WhenC++isanoption,Cis
probablyabetteroption.

http://yosefk.com/c++fqa/fqa.html 10/112
2/26/2015 C++ Frequently Questioned Answers
Anotherthingisalwaystrue:whereyoucanuseamanagedenvironment(wherethebehaviorofwrongprogramsis
defined),usingitwillsavealotoftrouble.C++(likeC)isdesignedforunmanagedenvironments(wherethebehaviorof
wrongprogramsisundefined).Unmanagedenvironmentsmakeitveryhardtolocatefaultsandimposenolimitonthe
damagedonebyanundetectedfault.Intheory,C++implementationscanruninmanagedenvironments,butinpracticethey
don'tbecauseofinnumerablecompatibilityissues.

Yetanotherthingisalmostalwaystrue:pickingupanewlanguageiseasierforanexperiencedC++programmerthan
workinginC++.ThisistheresultoftheexceedingcomplexityofC++.

Peoplewhothinkthere'snopointincomparingprogramminglanguages,forexamplebecause"businessconsiderations
dominatetechnicalconsiderations",arefreetostarttheirnewprojectsinCOBOL(COmmonBusinessOrientedLanguage).

[6.6]WhousesC++?
FAQ:Lotsandlotsandlotsofpeopleandorganizations.Whichisexcellentforbusinesssincealotofdevelopersare
available.

FQA:Empiricalstudiesindicatethat20%ofthepeopledrink80%ofthebeer.WithC++developers,theruleisthat80%of
thedevelopersunderstandatmost20%ofthelanguage.Itisnotthesame20%fordifferentpeople,sodon'tcountonthem
tounderstandeachother'scode.

Twothingsareatfault:theexceptionalcomplexityofC++anditswidepopularity,drivinghordesofpeoplewhodon't
considerprofessionalcompetenceapersonalpriority.Thefewcompetentdeveloperswillspendmuchoftheirtimedealing
withproblemscreatedbythelanguageinsteadoftheoriginalproblems(andasubsetofthesedeveloperswillnoteven
notice).

ThelargenumberofdevelopersatleasthastheadvantageofmotivatingthedevelopmentoftoolsfordealingwithC++
code.However,thedesignofthelanguagemakesitnotoriouslyhardtoproducesuchtoolsaproblemmotivationcan't
quiteremedy.ComparethequalityofcodebrowsinginC++IDEstoIDEsofotherlanguagesandyou'llgettheidea.You
canlookatlanguagespecificIDEs,generalpurposeprogrammingIDEsorextensionsforgeneralpurposetexteditorsC++
loseseverywhere.Don'tjustlookatsmallexamples,tryitonlargeprograms(especiallyonesusingcuttingedgetemplate
libraries).

[6.7]HowlongdoesittaketolearnOO/C++?
FAQ:In612monthsyoucanbecomeproficient,in3yearsyouarealocalmentor.Somepeoplewon'tmakeitthosecan't
learn,and/ortheyarelazy.Changingthewayyouthinkandwhatyouconsider"good"ishard.

FQA:In612monthsyoucanbecomeasproficientasitgets.Itisimpossibleto"know"C++itkeepssurprisingone
forever.Forexample,whatdoesthecodecout << pdowhenpisavolatilepointer?Hint:asexperiencedpeoplemight
expect,there'sanunexpectedimplicittypeconversioninvolved.

Whilesomepeoplearebetteratlearningthanothers,itisalsotruethatsomelanguagesareeasiertolearnandusethan
others.C++isoneofthehardest,andyourrewardfortheextraeffortspentlearningitislikelytobeextraeffortspentusing
it.IfyoufindithardtoworkinC++,tryinganotherlanguagemaybeagoodidea.

Beforeyousubvertthewayyouthinkaboutprogrammingandyourdefinitionof"good"inthiscontexttofitC++,itmightbe
beneficialtoaskthecommonsenseagain.Forexample,doescompilationtimereallycostnothing(isdevelopmenttimethat
cheap,aretherecompilationserverswith100GHzCPUsaround)?Isruntimereallypriceless(don'tuserkeystrokeslimit
outspeed,howmuchdataareweprocessinganyway)?HowefficientaC++constructreallyisinyourimplementation
(templates,exceptions,endlesscopying&conversion)?ThereasoningbehindC++maybeconsistent,buttheassumptions
almostneverhold.

LearningOOhasnothingtodowithlearningC++,anditisprobablybettertolearnOOusingadifferentlanguageasan
example.TheOOsupportinC++isalmostaparodyonOOconcepts.Forexample,encapsulationissupposedtohidethe
implementationdetailsfromtheuserofaclass.InC++,theimplementationishiddenneitheratcompiletime(changea
privatememberandyoumustrecompilethecallingcode)noratruntime(overwritememorywhereanobjectisstoredand
you'llfindoutalotabouttheimplementationofitsclassalthoughinanunpleasantway).

[6.8]WhataresomefeaturesofC++fromabusinessperspective?
FAQ:Hereareafew:

Ahugeinstalledbase,whichmeansgoodsupport

http://yosefk.com/c++fqa/fqa.html 11/112
2/26/2015 C++ Frequently Questioned Answers
Allowstoprovidesimplifiedinterfaces,reducingthedefectrate
Operatoroverloadingreduceslearningcurvesbyexploitingintuition
Reducessafetyvsusabilityandsafetyvsspeedtradeoffs
Makesitpossibleforoldcodetocallnewcode

FQA:Hereareafewmore:

NopracticalimplementationofC++runsinmanagedenvironments,increasingboththedefectrateandthepotential
damageofanundetecteddefect
ProvidingC++interfacestoasoftwarecomponentisimpossibleinpracticeduetolackofcompiletimeandruntime
interoperability
C++isextremelyinconsistentandcomplicated,increasinglearningcurvesandthedefectrate
C++compilerstypicallyfailtocomplytoitsintricatestandard,reducingportability
C++compilationisbothveryslowandveryfrequent,increasingdevelopmenttimeanddefectrate(peoplewritecryptic
anddangerouscodetoavoidrecompilation,forexample,useglobalvariablesinsteadofaddingargumentsto
functions,saving1.5hoursperrebuildx20developers=30hoursofdowntime)
C++lacksstandardtypesrepresentingbasicdatastructureslikestrings,arraysandlists(orhasmorethanone
standardandmanynonstandardones,whichisthesame),makingithardertoreusecode(eachinterfaceworkswith
adifferentkindofstrings)andreducingthespeedduetoruntimetypeconversion

AllthingsmentionedintheFAQarefalseformostpracticalpurposes:

Despitethe"huge"installedbase,thetoolsdealingwithC++codearepoorandtheirinteroperabilityisadisaster(in
bothcasestheproblemisinthelanguagedefinition)
C++interfacesareusuallyverycomplicated(lotsofsmallclasses,implicitlygeneratedfunctionslikeconstructors&
destructors,codebundledwiththeinterfaceintemplatedefinitions...).Asmentionedabove,providingC++interfaces
tosomeoneoutsideofyourteamisveryhardinpractice.Andprivatemembersareformanypurposeseffectivelya
partofyourinterface.
Operatoroverloadingisalmostalwayscounterintuitiveifonetriestounderstandthefunctionality(whydoestheleft
shiftoperatorprintthings?),andalwayscounterintuitiveifonetriestoestimateperformance(gofigureif*multiplies
twointegersortwomatrices,especiallyinsideatemplatedefinition)orlocatebugs(lethalonescanhideinplaceslike
operator=,wheretheyarehardtosee)
C++doesn'treducesafetyvsanythingtradeoffsinceit'sextremelyunsafe(it"supports"alltheundefinedbehaviorof
Clikebufferoverflows,addsmanynewscenarioswithundefinedresultlikeinvisibilityoftemplatespecializationsatthe
pointofusage,anditscomplexityreducesthechancesthatsomeoneactuallyknowswhataprogramdoesandcan
proveitscorrectness).Where'sthe"tradeoff"?
Oldcodecancallnewcodeinalmostanypopularlanguage,forexample,C(theancientqsortfunctionisprobably
callingnewcodeaswespeak).TheitemisreallysupposedtodescribethebenefitsofOOtonontechnicalpeople.
C++isnotlikelytogiveitsuserthebenefitsofOO.

[6.9]Arevirtualfunctions(dynamicbinding)centraltoOO/C++?
FAQ:Sure,that'swhatmakesC++anobjectorientedlanguage.Don'tswitchfromCtoC++unlessyouneedvirtual
functions!

FQA:TheyprobablyareifyouconsiderC++an"objectoriented"language(aC++debuggerdoesn'ttryaskingittoshow
what"object"islocatedatarandomplace,forexample).Youhavetocarefullydefine"objectoriented"sothatC++fitsthe
definition.

Dynamicbindingiscentraltoanylanguagesinceotherwiseoldcodecan'tcallnewcode,makingcodereuseveryhard.
VirtualfunctionsareoneformofdynamicbindingsupportedbyC++(functionpointers,inheritedfromC,areanotherone).

SwitchingfromanylanguagetoC++isnotnecessarilyagoodidea.

[6.10]I'mfromMissouri.Canyougivemeasimplereasonwhyvirtual
functions(dynamicbinding)makeabigdifference?
FAQ:BeforeOO,youcouldonlyreuseoldcodebyhavingnewcodecallit.WithOO,oldcodecancallnewcodemore
reuse.Evenifthesourcecodefortheoldcodeisnotavailable.

FQA:ItisunclearwhytheFAQgetsthiswrongmostofthetimeitistechnicallyaccurate.Dynamicbindingoldcode
callingnewcodeexistsoutsideofOO.Therearecountlessexamplesonanyscale,rangingfromtheCqsortfunctionto
operatingsystems,whichrunprogramswrittenlongafterthecodeofthosesystems.

http://yosefk.com/c++fqa/fqa.html 12/112
2/26/2015 C++ Frequently Questioned Answers
ThespecialthinginOOisthat,well,itworkswithobjects.Inthecaseofdynamicbinding,thismeansthatnotonlydoesold
codecallnewcodeitalsopassesthestate(encapsulatedintheobjectreceivingthemethodcall)neededforthisnewcode
towork.ThisalsohappensoutsideofOO,butOOisanexcellentunifyingframeworkfordealingwiththiskindofthing.
EspeciallyifyouhaveagoodOOenvironment.

TheomissionoffactsintheFAQismuchmoretypicalthanthetechnicalinaccuracy.Specifically,there'sadifference
betweentheoryandpracticewhenitcomestooldcodenotavailableinsourceformcallingnewcode.Inpractice,code
generatedfromC++sourceisnotportable,limitingthescenarioswherethereuseactuallyworks.Worse,evenC++
implementationsrunningonthesamehardwareandoperatingsystemarerarelycompatible.Foractuallyhavingoldcode
callnewcode,youmustlimityourselftoasmallsubsetofthelanguage(Cisonegoodone),and/orhaveboththeoldand
thenewcodebuiltwiththesametoolsunderthesamesettings.

[6.11]IsC++backwardcompatiblewithANSI/ISOC?
FAQ:Almost.ButadeclarationofafunctionwithoutparametersmeansdifferentthingsinCandC++,andsizeof('x')is
likelytoyieldadifferentvalue,and...

FQA:Thepairofwords"almostcompatible"isalmostmeaninglessformanytechnicalpurposes,compatibilityisabinary
thing."Compatible",ontheotherhand,canhaveseveralmeanings.

Ifyourquestionis"CanIcompileCcodewithaC++compiler?",theansweris"no"becauseofnumerousdifferencesinthe
waycodeisinterpreted(somethingswillbereportedbythecompiler,somewillbesilentlymisinterpreted).However,thisis
notarealproblem,sinceyoucancompileCcodewithaCcompiler.

Ifyourquestionis"CanIcallCcodefromC++code?",theansweris"yes",butit'snotspecialtoC++.YoucancallCcode
fromvirtuallyanypopularlanguagebecausemostoftoday'senvironmentsarebasedonC,makingitbotheasyand
beneficialtosupportthis.

Ifyourquestionis"CanIcallC++codefromCcode?",theansweris"sometimes".ItispossibleiftheC++codeexposesa
Cinterface(noclasses,noexceptions...),andeventhenthereareproblemslikemakingsureC++globalconstructorsand
destructorsareinvoked.Manyplatformsprovidewaysforthistowork.

Ifyourquestionis"IsiteasierforaCprogrammertolearnanduseC++thananothernewlanguage,possiblyobject
oriented?",theansweris"no".C++isveryhardtolearnanduseandthehardestpartsarenotrelatedtotheCsubset,butto
thenewpartsandthewaytheyinteractwiththeoldparts.

Ifyourquestionis"AreC++programslikelytocontainbugssimilartotheselitteringCprograms,likebufferoverflows?",the
answeris"yes".Ifyouarewillingtosacrificeperformancetogainstability,amanagedenvironmentmightsuityourneeds.If
youwanttoimprovethestabilityofyourprogramswithoutsacrificingneitherdevelopmenttimenorruntime,youprobably
can't.Inparticular,the"highlevel"C++iscompatibletothe"lowlevel"Cwhenitcomestodamagecausedbylowlevel
errors.

[6.12]IsC++standardized?
FAQ:Yes,anISOstandardwasadoptedin1997.TheFAQmentionstwicethatitwas"adoptedbyunanimousvote".

FQA:Yes,thereisadocumentspecifyingwhat"C++"means,andlotsofimplementationvendorssignedit.Theimportant
thingaboutstandardization,however,isthepracticalimplications.Let'sexaminethem.

TheC++standarddoesnotspecifywhatsourcecodeistranslatedto.UnlikecodebuiltfromJavasource,compiledC++
codewillusuallyonlyrunononehardware/OSconfiguration.

TheC++standarddoesnotaddressinteroperabilitybetweenimplementations.UnlikecodebuiltfromCsource,compiled
C++codewillonlybeabletocallC++codebuiltwiththesamecompilerandthesamesettings.Differentimplementations
implementexceptions,globalinitialization&destruction,virtualfunctions,RTTI,manglingconventions,etc.etc.differently.
TheCstandardleavesoutinteroperabilitybetweenimplementationsjustliketheC++standardbutCisanorderof
magnitudesimpler,soyouwon'thavetheseproblemsinpractice.

TheC++standarddoesnotdefineatermlike"module"or"library"only"program"and"translationunit"(roughly,thelatter
meansapreprocessedsourcefile).Ifyoudeliverdynamically/staticallylinkedlibraries,you'reonyourown.Again,youwill
haveproblemswithglobalinitialization&destruction,RTTI,exceptions...

TheC++standarddoesnotspecifyamachinereadabledefinitionoftheC++grammar,andthequestionwhetheragiven
sequenceofcharactersislegalC++isundecidable.BuildingtoolsreliablyprocessingC++code(includingcompilers)is
extremelyhard.

http://yosefk.com/c++fqa/fqa.html 13/112
2/26/2015 C++ Frequently Questioned Answers
TheC++standardhasbeenoutthereforalongtime.Today,differentC++compilerswillinterpretC++codedifferently.The
mostfrequentsourceofproblemsisstaticbindingfiguringoutwhatfunctioncallsshouldbegeneratedfromagiven
statement.Compilersimplementnameresolution(affectedbynamespaces,function&operatoroverloading,template
signaturematching&specialization,implicittypeconversions,typequalifiers,inheritance...)differently.Neitherthestandard
documentnorcommonsensewilleasilytellyouwhichcompileris"right".

Youmaythinkthatcompilerswilleventuallycatchupwiththestandard(whichmostvendorsaretryingtodoallthetime,but
thetoolsstillfrequentlydisagreeonthequestionwhat"C++"means).Well,thenextversionofthestandardissupposedto
beadoptedbefore2010,givingthosevendorssomemorework.Forthosecompilerwriterswithreallytoomuchtimeontheir
hands,there'sC++/CLI.

C++isstandardized,butitmayhavelesspracticalbenefitsthanyoumightbeusedtoexpectfrom"standards".

[6.13]WherecanIgetacopyoftheANSI/ISOC++standard?
FAQ:Getreadytospendsomemoney.Alistoflinksfollows.

FQA:Getreadytothrowawaysomemoney.Seriously,whatareyougoingtodowithyourcopy?Thedocumentis
incomprehensible.

Thedocumentmaybeusefulifyouarealanguagelawyerplanningtosuethepeopleresponsibleforthelanguageora
particularimplementation.Butifyouwanttobuildworkingsoftware,it'smorepracticaltoacceptthefactthatyour
implementationisnotstandardcompliantinmanydarkareas.Ifyoufindafrontendbug(forexample,manytimesnifty,
expensivetoolswillcrashtryingtoprocesscomplicatedC++codeallcompilersIuseddid)that'sactuallyyourproblem.
WhileyouarelostinthemazeofC++features,yourcompetitorhasalreadyreleasedaworkingproductwrittenwithoutsuch
complications.

Thedocumentisalsousefulifyou'reintometaprogramming(compilers/debuggers/profilers/verifiers...)andwanttowrite
toolsdealingwithC++code.Thestandardmayhelpchillyourpassionbeforeyouthrowawaytoomuchofyourtime.

[6.14]Whataresome"interviewquestions"Icouldaskthatwouldletme
knowifcandidatesreallyknowtheirstuff?
FAQ:Ifyouareanontechnicalperson(manager/HR),askatechnicalpersontohelpyoujudgethetechnicalcompetenceof
acandidate.Ifyouareatechnicalperson,theFAQisonesourceofgoodquestions,separatingthetrulycompetentpeople
fromtheposers.

FQA:Thegoodinterviewquestionsprobablydon'tmentionanythinguniquetoC++.

Ultimately,youarelookingforpeoplewithgoodwill(somecallthem"cooperative"),whowilldothings,notjusttalkabout
them(somecallthem"practical"),andwhowillthink,notjustdo(somecallthem"intelligent").Sothebestquestions,
relevantforallcandidates,areabouttheirlargestlastprojects.Theanswersgiveyoulotsofinformationandgoodanswers
arealmostimpossibletofake.

Youmayalsoneedpeopletohavesomepriorknowledgerelevanttotheirworksinceyoudon'thavetimetohavethem
trainedandgainexperience.Ifyouaresurethat'sthecase(despitethefactthatthepeopleyouarelookingforaregood
learners),askspecificquestions.Questionsabouthighlevelsoftwareorganizationissues(likeOO)maybeuseful.
Questionsaboutlowlevelsoftwareconstructionissues(likepointers)maybeuseful.TheseissuesarenotspecifictoC++.

AskingaboutthingsspecifictoC++isnotveryuseful.

First,manyofthesethingsareuselessforanypracticalpurposeandarebestavoided.Whethersomeoneknowsthese
thingsiscorrelatedquitelooselywithproficiency,andtherearemanyexcellentdevelopersouttherewhoweren'tconfronted
withaparticularobscureC++featureyet,orsuccessfullyforgotit.Sochancesarethatyouaregoingtorejectagood
candidate.

Second,agoodcandidateactuallyknowingtheanswermaypreferanemployeraskingmorerelevantandpractical
questions.Sochancesarethatagoodcandidateisgoingtorejectyou.

Andthird,therearepeoplewholookforthemostcomplicatedwaytosolveaproblemtoshowofftheirintelligence.These
tendtostumbleintothedarkareasofthetoolstheyuseallthetime,sotheywillknowanswerstomanyC++specific
questions(theywon'tknowanswerstomanymore,becausealmostnobodydoes).Yourquestionswillrankthesepeopleas
thebestpossiblecandidates.Lateryouwillfindoutthatthesepeoplearepoorpractitioners.

http://yosefk.com/c++fqa/fqa.html 14/112
2/26/2015 C++ Frequently Questioned Answers

[6.15]WhatdoestheFAQmeanby"suchandsuchisevil"?
FAQ:Thismeansthatafeatureshouldbeavoidedwheneverpossible.Thestrongwordissupposedtohelppeoplechange
theiroldthinking.

FQA:Thismeansthefeaturesatisfiesthefollowingconditions:

ItisinheritedfromC
Itiseasytoabuse(especiallywhenitinteractswiththenewC++features)
Itcancauseproblemswhenabused(especiallywhenitinteractswiththenewC++features)
C++providesoneormorefacilitiesduplicatingthefunctionalityofthefeature,replacingtheoriginalproblemswithnew
andmuchmorecomplicatedproblems

Forexample,macros,pointers,andarraysmeetthisdefinition(thecorrespondingC++"solutions"areconst&template,
references&smartpointers,andvector/stringclasses).Includefilesalmostmeetthisdefinition,exceptthatC++doesn't
duplicatethisfunctionality(namespacesareaparallelnotionof"modules",buttheycan'tbeusedtolocatedefinitions).
Consequently,theFAQwillnotcallincludefiles"evil".Ontheotherhand,functionoverloadingdoesn'tcomefromC,so
duplicatefacilitiesliketemplatespecialization,defaultarguments,etc.arenotenoughfortheFAQtocallfunction
overloading"evil".Still,functionoverloadingisverycommonlyabusedleadingtomajorproblems.

AC++userislikelytohaveadifferentdefinitionof"evil".Auserdoesn'tcarewhethersomethingcamefromCornot,and
whetherC++triedtoofferduplicatefacilities(whileforcinguserstodealwiththeoriginalonessincethey'restillinthe
language).Ausertypicallycaresaboutthe"easytoabuseandcausingtroublewhenabused"parts.Lotsandlotsofpartsof
C++arelikethat.

AstothefeaturestheFAQdoescallevilwhyaretheyinthelanguage?Isitgoodfortheusersofthelanguage,orforthose
whodesignedandpromotedit?

[6.16]WillIsometimesuseanysocalled"evil"constructs?
FAQ:Ofcourse!Evilmeans"usuallyundesirable",butsometimesyouhavetochoosefromasetofbadoptions,andan
"evil"featureisyourbestoption.Therearenouniversalrules.Think!AtthispointtheFAQ(andyourtypicalC++devotee)
getsquiteagitated.

FQA:Ofcourse!Youhavenochoice.Theyarebuiltintothelanguage.Forexample,"abc"and{1,2,3}areevilarrays,the
keywordthisandthestandardchar** argvareevilpointers,andyou'llneedanevil#definetodefineausableinterface(for
theheaderfileinclusionguards).

Notethatwithevilarrays,youcanwriteint a[3] = {1,2,3};whilewiththesupposedlylessevilstd::vector,youcan't.


You'llfindoutthatC++brandnewfeaturesduplicatingthefunctionalityofthe"evil"oldCfeaturesareinferiortothelatterin
manymoreways.

Worse,youcanavoidneitherthefeaturestheFAQcallsevilnortheonestheuserwouldcallevil,becauseifyourcode
doesn'tuseafeature,itdoesn'tmeanthatsomeoneelse'scodeyouhavetolivewithdoesn't.Forexample,youmaytryto
avoidexceptions,buttheC++operator new,aswellascodeinthirdpartylibraries,willthrowexceptions,andyouhaveto
catchthem.

There'sabasicassumptionbehindC++thatextrafeaturescan'tbeaproblemonlymissingfeaturescan.That'swhythere
aresomanyfeaturesinC++,andinparticularsomanyduplicateones.Realworldanalogies("imagineadogwithtwelve
legs")arepalecomparedtothisreality.

[6.17]Isitimportanttoknowthetechnicaldefinitionof"goodOO"?Of"good
classdesign"?
FAQ:Notifyouareapractitioner.Businessconsiderationsaretheimportantones.Precisetechnicaldefinitionsof"good"
mayleaddeveloperstoignoretheseconsiderations,sotheyaredangerous.

FQA:Whetherit'simportantornot,thereisnotechnicaldefinitionof"good",inparticulargoodOOorgoodclassdesign.
"Good"isnotaformalterm,norisituniversal.Forexample,ifyouworkforacompany,it'simportanttoconsiderhow
beneficialsomethingultimatelyisforthatcompanyinordertodefine"good".

However,therearetechnicaldefinitionsofOO.SowhiletherearenoformalmeanstotellwhethersomethingisgoodOO,
youmaybeabletoreasonwhethersomethingisOOornot.Whichisnotnecessarilyinterestingbyitself.Butitmaybe
interestingifyouhavereasonstobelievethatOOisagoodtoolforyourjobyoumaywanttomakesureyou'llactuallyget
http://yosefk.com/c++fqa/fqa.html 15/112
2/26/2015 C++ Frequently Questioned Answers
thebenefitsyouexpect.ItmayalsobeinterestingifsomeonecallssomethingOOyoumaywonderwhetheryouusethe
sametermsorwhethertheyknowwhatthey'retalkingabout.

Gettingobsessiveaboutprecisedefinitionsisabadwaytomakedecisions.Butit'salsobadtoignoredefinitionsandblindly
gowiththehype.Forexample,peoplepromotingC++keeptellinghowgoodOOis,andhowC++supportsOO,andthen
youtrytofindoutwhatOOactuallymeans,andsuddenlyitturnsoutthatit'snotimportant.Isn'tthatalittlestrange?

ItisverybeneficialforapractitionertogainfamiliaritywithOOsystemsotherthanC++,andwithOOdefinitionsotherthan
the"encapsulation,inheritance,polymorphism"trinityinterpretedinspecialwaysallowingC++tobeconsidered"OO".For
example,aclaimthatanenvironmentlackingboundarycheckingorgarbagecollectionisnotanOOenvironmentsounds
outrageoustopeopleaccustomedtoC++.Butfrommanyperspectives,itmakesalotofsense.Ifanyonecanoverwritean
object,where'sthe"encapsulation"?Ifdisposinganobjectcanleadtodanglingreferencesormemoryleaks,howisthe
system"objectoriented"?Whatabouttheabilitytotellwhatkindofobjectislocatedatagivenplaceandtime?Yousaythe
softwareworkswithobjectswherearethey?Andifonecan'tfindout,howisonesupposedtodebugthesoftware?

WhenpeopleclaimthatC++isobjectorientedandtherefore"good",itmaybeworthcheckingwhetheryournotionof"good"
issimilartotheirsfromabusinessperspective,forexample.

[6.18]WhatshouldItellpeoplewhocomplainthattheword"FAQ"is
misleading,thatitemphasizesthequestionsratherthantheanswers,and
thatweshouldallstartusingadifferentacronym?
FAQ:Thesepeopleshouldgetalife.Changingatermusedandunderstoodbymanypeopleispointless,becausepeople
nolongercareabouttheoriginsofthetermanddirectlyassociateitwiththerightmeaning.

FQA:Ifpeopleareaccustomedtoexpressanideainacertainway,anditworksforthem,tryingtoconvincethemtousea
newwayservesnousefulpurpose.Wecouldusetheopportunitytoasknitpickingquestionsabouthowthiswisdomis
appliedtoC++itself.Forexample,whywouldsomeonedeprecatestaticvariablesatthetranslationunitscopeand
demandpeopletouseanonymousnamespacestogetidenticalbehavior?Andallthat.

Instead,we'llusetheopportunitytopointoutthatatthetimeofwriting(2007),"FQA"appearstobealesspopularacronym
than"FAQ":aGooglesearchyieldsafewresults,butaWikipediasearchdoesnot.Still,changing"FQA"tosomethingelse
inthisdocumentisnotanoption:it'sallovertheplace.

Classesandobjects
OneofthestatedgoalsofC++issupportforobjectorientedprogramming.ThispageintroducesC++classesandoutlines
thetacticstheyusetodefeattheirpurpose.

[7.1]Whatisaclass?
[7.2]Whatisanobject?
[7.3]Whenisaninterface"good"?
[7.4]Whatisencapsulation?
[7.5]HowdoesC++helpwiththetradeoffofsafetyvs.usability?
[7.6]HowcanIpreventotherprogrammersfromviolatingencapsulationbyseeingtheprivatepartsofmyclass?
[7.7]IsEncapsulationaSecuritydevice?
[7.8]What'sthedifferencebetweenthekeywordsstructandclass?

[7.1]Whatisaclass?
FAQ:InOOsoftware,"thefundamentalbuildingblock".

Aclassisatypearepresentationforasetofstates(muchlikeaCstruct)andasetofoperationsforchangingthestate
(movingfromonestatetoanother).Classesaresimilartobuiltintypesinthissense(forexample,anintholdsabunchof
bitsandprovidesoperationslike+and*).

FQA:That'sacorrecttheoreticaldefinition.It'sequallyapplicabletoallOOlanguages,buttheyaredifferentwhenitcomes
tomorespecific,practicalaspectsoftheirparticularimplementationofclasses.

HowdoIcreateobjects?Andwhathappenswhentheyarenolongerneeded?Isitmyjobtofigureoutwhichonesare
unusedanddeallocatethem?Bad.

http://yosefk.com/c++fqa/fqa.html 16/112
2/26/2015 C++ Frequently Questioned Answers
WhathappensifIhavebugs?IfIhaveapointertoanobject,canitbeinvalid(bearandombitpattern,pointtoadead
object)?Itcan?Theprogramwillcrashorworse?Whataboutarraysofobjectsandoutofboundsindexes?Crashora
modificationofsomeotherrandomobject?Youcallthatencapsulation?Bad.

WhathappensifIchange/add/removeaprivatevalue,withoutchangingtheinterface?Allcodeusingtheclasshastobe
recompiled?Ibetyoucallthatencapsulation,too.Bad.

Idon'tlikeC++classes.

[7.2]Whatisanobject?
FAQ:Achunkofmemorywithcertainsemantics.Thesemanticsaredefinedbytheclassoftheobject.

FQA:Theyarealsodefinedbythebugswhichcausethecodetooverwritedataoftheseobjectswithoutbotheringtouse
theinterfacedefinedbytheclass.Peoplewhothinkthatrealprogrammerswritecodewithoutbugsneedtoupgradetoa
humanbrain.

Still,itsoundsinteresting:thememoryofourC++programisapparentlybrokenintochunksstoringobjectsofvarious
classes,with"definedsemantics".Looksverypromising,that.Forexample,wecouldaskadebuggeraboutthekindof
objectlocatedatsuchachunkandinspectitsdata(asin"thisisaPointwithx=5andy=6").Wecouldeventakethisone
stepfurtherandimplementthingslikegarbagecollectors,whichcancheckwhetheranobjectisusedbylookingforpointers
toitintheplaceswhicharesupposedtostorepointers.

Unfortunately,youcan'ttelltheclassofaC++objectgivenapointertoitatruntime.SoifyoudebugacrashedC++
programandfindapointersomewhereinitsguts,andyoudon'tknowitstype,you'llhavetoguessthat
"0000000600000005"isaPoint.Whichiscompletelyobvious,becausethat'sthewayapairofadjacentintegerslookslikein
hexadecimalmemorylistingsofalittleendian32bitmachine.AndtwoadjacentintegersmightbeaPoint.Orsomeother
twointegerstructure.Orapartofathreeintegerandafloatstructure.Ortheymightbetwounrelatednumberswhichjust
happentobeadjacent.

Whichiswhyyoucan'tautomaticallycollectthegarbageofC++programs.

[7.3]Whenisaninterface"good"?
FAQ:Itisgoodwhenithidesdetails,sothattheusersseeasimplerpicture.Itshouldalsospeakthelanguageoftheuser
(adeveloper,notthecustomer).

FQA:Um,sometimesyouwanttheinterfacetoexposethemanydetailsandspeakthelanguageofthemachine,although
it'sprobablynotverycommon.Thegenericanswerissomethinglike"aninterfaceisgoodifitgetstheusersomewhere".

Forexample,usingOpenGLyoucanrendernifty3Dstuffatrealtimeframerates.FFTWdelivers,well,theFastestFourier
TransformintheWest.WithQt,youcandevelopcrossplatformGUI,and"crossplatform"won'tmean"lookinglikean
abandonedstudentproject".Writingthatstufffromscratchislotsofworkusingthelibrariescansavelotsofwork.
Apparentlylearningtheinterfacesoftheselibrariesisgoingtopayoffformanypeople.

Foranegativeexample,consider<algorithm>.Doesstd::for_eachgetusanywherecomparedtoabareforloop,except
thatnowweneedtodefineafunctorclass?That'sabadinterface,becauselearningitdoesn'tmakeiteasiertoachieve
anythinguseful.

[7.4]Whatisencapsulation?
FAQ:Thepreventionof"unauthorizedaccess"tostuff.

Theideaistoseparatetheimplementation(whichmaybechanged)fromtheinterface(whichissupposedtobestable).
Encapsulationwillforceuserstorelyontheinterfaceratherthantheimplementation.Thatwillmakechangingthe
implementationcheaper,sincethecodeoftheuserswon'tneedtobechanged.

FQA:That'sanicetheoreticaldefinition.Let'stalkaboutpracticethepropertiesoftheC++keywordsprivateand
protected,whichactuallyimplementencapsulation.

Thesekeywordswillcausethecompilertoproduceanerrormessageuponaccesstoanonpublicmemberoutsideofthe
class.However,theywillnotcausethecompilertoprevent"unauthorizedaccess"bybuggycode,forexampleuponbuffer
overflow.IfyoudebugacrashedormisbehavingC++program,forgetaboutencapsulation.There'sjustoneobjectnow:the
memory.

http://yosefk.com/c++fqa/fqa.html 17/112
2/26/2015 C++ Frequently Questioned Answers
Astothecostofchangestothetheprivatepartstheytriggerrecompilationofallcodethat#includesyourclassdefinition.
That'stypicallyanorderofmagnitudemorethan"codeactuallyusingyourclass",becauseeverythingendsupincluding
everything."Thekeymoneysavinginsight",asthebusinessfriendlylookingFAQputsit,isthateverytimeyouchangea
classdefinition,youarerecompilingtheprogramsusingit.Here'sanothersimpleobservation:C++compilesslowly.And
whatdowegetnowwhenweputtwoandtwotogether?That'sright,kidswithC++classes,thedevelopersgetpaid
primarilytowaitforrecompilation.

Ifyouwantsoftwarethatis"easytochange",stayawayfromC++classes.

[7.5]HowdoesC++helpwiththetradeoffofsafetyvs.usability?
FAQ:InC,stuffiseitherstoredinstructs(safetyproblemnoencapsulation),oritisdeclaredstaticatthefile
implementinganinterface(usabilityproblemthereisnowaytohavemanyinstancesofthatdata).

WithC++classes,youcanhavemanyinstancesofthedata(manyobjects)andencapsulation(nonpublicmembers).

FQA:Thisiswildlywrong,andthechancesthattheFAQauthordidn'tknowitareextremelylow.That'sbecauseyoucan't
useFILE*from<stdio.h>orHWNDfrom<windows.h>orinfactanywidelyusedand/ordecentClibrarywithoutnoticingthat
theFAQ'sclaimiswrong.

WhenyouneedmultipleinstancesandencapsulationinC,youuseaforwarddeclarationofastructintheheaderfile,and
defineitintheimplementationfile.That'sactuallybetterencapsulationthanC++classesthere'sstillnoruntime
encapsulation(memorycanbeaccidentally/maliciouslyoverwritten),butatleastthere'scompiletimeencapsulation(you
don'thavetorecompilethecodeusingtheinterfacewhenyouchangetheimplementation).

ThefactthatacrudeCtechniqueforapproximatingclassesisbetterthanthesupportforclassesbuiltintotheC++language
isreallyshameful.ApparentlysoshamefulthattheFAQhadtodistortthefactsinanattempttosaveface(orelsethe
readerswouldwonderwhetherthere'sanypointtoC++classesatall).TheFQAherebydeclaresthatitwillnotgodownthis
path.Therefore,wehavetomentionthis:theforwarddeclarationbasicallymakesitimpossibleforthecallingcodeto
reservespacefortheobjectatcompiletime.ThismeansthatastructdeclaredinaheaderfileoraC++classcan
sometimesbeallocatedmoreefficientlythanaforwarddeclaredstruct.However,thisisreallyaboutadifferenttradeoff
safetyvs.efficiency,andthere'snoescapefromthistradeoff.Eitherthecallerknowsaboutthedetailssuchasthesizeofan
objectatcompiletimewhichbreakscompiletimeencapsulationoritdoesn't,soitcan'thandletheallocation.

Anyway,here'stherealanswertotheoriginalquestion:C++helpswiththetradeoffofsafetyvs.usabilitybyeliminating
both.

C++isextremelyunsafebecauseeverypointercanbeusedtomodifyeverypieceofmemoryfromanypointincode.C++is
extremelyunusableduetocrypticsyntax,incomprehensiblesemanticsandendlessrebuildcycles.Where'syourtradeoff
now,sillyCprogrammers?

[7.6]HowcanIpreventotherprogrammersfromviolatingencapsulationby
seeingtheprivatepartsofmyclass?
FAQ:Don'tbother.Thefactthataprogrammerknowsabouttheinnerworkingsofyourclassisn'taproblem.It'saproblemif
codeiswrittentodependontheseinnerworkings.

FQA:That'sright.Besides,peoplecanalwaysaccessthecodeifamachinecan.Preventingpeoplefrom"seeing"thecode
inthesensethattheycanaccessit,butnotunderstanditisobfuscation,notencapsulation.

[7.7]IsEncapsulationaSecuritydevice?
FAQ:No.Encapsulationisabouterrorprevention.Securityisaboutpreventingpurposefulattacks.

FQA:Dependsonthekindof"encapsulation".Somemanagedenvironmentsrelyontheirsupportforruntime
encapsulation,whichmakesittechnicallyimpossibleforcodetoaccessprivatepartsofobjects,toimplementsecurity
mechanisms.C++encapsulationevaporatesatruntime,andisalmostnonexistentevenatcompiletimeuse#define
private publicbeforeincludingaheaderfileandthere'snomoreencapsulation(correction).It'shardly"encapsulation"at
all,soofcourseithasnosecurityapplicationssecurityisharderthanencapsulation.

ThecapitalEandSinthequestionareveryamusing.IwonderwhethertheyareamanifestationofDeepRespectfor
BusinessValuesorSoftwareEngineeringbothoptionsareequallyhilarious.

http://yosefk.com/c++fqa/fqa.html 18/112
2/26/2015 C++ Frequently Questioned Answers

[7.8]What'sthedifferencebetweenthekeywordsstructandclass?
FAQ:Bydefault,structmembersandbaseclassesarepublic.Withclass,thedefaultisprivate.Neverrelyonthese
defaults!Otherwise,classandstructbehaveidentically.

Buttheimportantthingishowdevelopersfeelaboutthesekeywords.structconveysthefeelingthatitsmembersare
supposedtobereadandmodifiedbythecodeusingit,andclassfeelslikeoneshouldusetheclassmethodsandnotmess
withthestatedirectly.Thisdifferenceistheimportantonewhenyoudecidewhichkeywordtouse.

FQA:structisaCkeyword.classwasaddedtoC++becauseitiseasierthanactuallymakingthelanguageobject
oriented.Anditdoesagoodjobwhenitcomestothefeelingofanewbiewhoheardthat"OOisgood".

CheckouttheemotionaldiscussionaboutwhichkeywordshouldbeusedintheFAQ.ThemoresimilartwoduplicateC++
featuresare,themoreheatedtheargumentaboutthebestoptiontouseineachcasebecomes.Pointers/references,
arrays/vectors...Yawn.

Bytheway,theforwarddeclarationofstructthingworksinC++,andit'sbetterthanaclasswithoutvirtualfunctionsmost
ofthetime.

Inlinefunctions
Inlinefunctionsareapetfeatureofpeoplewhothinktheycareaboutperformance,butdon'tbothertomeasureit.

[9.1]What'sthedealwithinlinefunctions?
[9.2]What'sasimpleexampleofproceduralintegration?
[9.3]Doinlinefunctionsimproveperformance?
[9.4]Howcaninlinefunctionshelpwiththetradeoffofsafetyvs.speed?
[9.5]WhyshouldIuseinlinefunctionsinsteadofplainold#definemacros?
[9.6]Howdoyoutellthecompilertomakeanonmemberfunctioninline?
[9.7]Howdoyoutellthecompilertomakeamemberfunctioninline?
[9.8]Isthereanotherwaytotellthecompilertomakeamemberfunctioninline?
[9.9]Withinlinememberfunctionsthataredefinedoutsidetheclass,isitbesttoputtheinlinekeywordnexttothe
declarationwithintheclassbody,nexttothedefinitionoutsidetheclassbody,orboth?

[9.1]What'sthedealwithinlinefunctions?
FAQ:Inliningafunctioncallmeansthatthecompilerinsertsthecodeofthefunctionintothecallingcode(whichis
technicallydifferent,butlogicallysimilartotheexpansionof#definemacros).Thismayimproveperformance,becausethe
compileroptimizesthecalleecodeinthecontextofthecallingcodeinsteadofimplementingafunctioncall.However,the
performanceimpactdependsonlotsofthings.

There'smorethanonewaytosaythatafunctionshouldbeinline,someofwhichusetheinlinekeywordandsomedon't.
Nomatterwhatwayyouuse,thecompilermightactuallyinlinethefunctionanditmightnotyou'rejustgivingita"hint".
Soundsvague?Itisanditisgood:itletsthecompilergeneratebetterand/ormoredebuggablecode.

FQA:Tosummarize:thecompilerhastherighttoinlineornotinlineanyfunction,whetherit'sdeclaredinlineinanyofthe
severalwaysornot.Doesn'tthismake"inlinefunctions"ameaninglessterm?

It'simpossibletomakeanysenseofthiswithoutdiscussingthehistoryofactualimplementationsoftheClanguagetool
chaincompilers,assemblersandlinkers.AstraightforwardCimplementation(whichoriginallyallofthemwere)workslike
this.First,acompilergeneratesassemblycodefromeachsourcefile,separately(withoutlookingatothersourcefiles).Then
theassemblerconvertstheassemblycodetoan"objectfile",where"object"means"asequenceofbytes"(talkabout
"objectoriented").Forexample,afunctionisonekindof"object"thebytesencodethemachineinstructionsthecompiler
usedtoimplementit.

Thevaluesofthebytesmakingupthese"objects"arealmostcompletelyfinalizedatthisstage.Theonlykindof"unknowns"
isaddressesof"objects"whenan"object"referstoanaddressofanother"object"(say,afunctioncallsanotherfunction),
theassemblercan'tcomputetheactualvaluesofthebytesmakingupthefunctioncallinstructions.Thisisdonebythe
linker,whichallocatesthe"objects"(basicallybyconcatenatingthem).Thelinkerthenresolvesthereferences(suchas
functioncalls)totheaddressesofthe"objects".

Whatthismeansisthattheonlywaytoinlinefunctionsisto#includetheirdefinitionintheheaderfileotherwise,the
compilerdoesn'tseethecodeofthefunction,andthelinkercan'tdoinlining,becauseallitseesisbytesequences,andit
wouldhavetodecompilethemfirst.Whichexplainswhyyouneedtoincludethesourcecodeofinlinefunctionsinheader
http://yosefk.com/c++fqa/fqa.html 19/112
2/26/2015 C++ Frequently Questioned Answers
files,butdoesn'texplainwhyyouneedaninlinekeywordandotherwaystoexplicitlydeclareafunctionas"inline".Afterall,
thecompilerisfreetoignorethesehints,sowhat'stheirpoint?

Well,thepointisthatthecompilercan'ttellan#includedfunctionfromonewritteninyoursourcefile,becausethat'showC
preprocessingworksthecompileronlyseesonelargefileofcode.Sounlessyouexplicitlydeclarethe#includedfunctions
"inline",itwillgeneratetheircodelikeitdoeswithnormalfunctions.Thenthelinkerwillcomplainaboutmultipledefinitions.

Here'showcodeiscompiledbymanymoderncompilers,includingsomeCandC++compilers.Thecompilertransformsthe
sourcecodetoanintermediaterepresentation,"lower"thanthesourcelanguagebut"higher"thanassemblylanguage.This
makesitpossibletodoinliningatlinktime,eitheronaperlibraryorawholeprogrambasis.Themachinecodeisonly
generatedasthefinallinkagestep,oritcanevenbedelayeduntilruntime(thesocalled"justintimecompilation").This
way,youdon'thavetosplityourfunctionsto"inline"(thosethatcanbeinlined,butthecompilergetstodecideifthey
actuallyareinlined)andtherest(thosethatjustcan'tbeinlined).Instead,youletthecompilermakethedecisionforall
functions.Unfortunately,themeaningofCandC++isdefinedwiththeoldsortofimplementationinmind,andhavingnewer,
moresophisticatedimplementationsaroundcan'tchangeit.

[9.2]What'sasimpleexampleofproceduralintegration?
FAQ:There'sanexampleofafunctioncallinganotherfunctionandhowinliningmaysaveyoucopyingtheparameterswhen
youpassthemtoafunctionandcopyingtheresultitreturnsandstuff.There'salsoadisclaimersayingthatit'sjustan
exampleandmanydifferentthingscanhappen.

FQA:Basically,codemaybeportable,butperformanceistypicallynot.Forexample,inliningafunctionmaymakecode
fasterorslower,dependingonlotsofthingsdiscussedinthenextFAQs.Thisisonereasontoleavethedecisiontoa
compiler,because"itunderstandsthetargetplatformbetter".Thisisalsoareasontoleavethedecisiontoahuman,
becausecompilersdon'treallyknowthetargetplatformverywell(theyknowthetargetprocessorbutnottheentiresystem),
andbecausetheydon'tunderstandtheproblemyouaresolvingatall(sotheycan'ttellhowmanytimeseachpieceofcode
islikelytorun,etc.).

Anyway,theproblemof"helpingthecompilertooptimizecode"byadding"hints"tothecode,especiallyportablecode,is
quitehard.Therearemanythingssimilartoinlininginthisrespect(forexample,loopunrolling).Whichiswhythere'sno
unrollkeywordforcingloopunrolling.Andtheinlinekeywordonlyexistsbecausethere'snobetterwaytoenable(as
opposedto"force")inlininginC/C++.

[9.3]Doinlinefunctionsimproveperformance?
FAQ:Sometimestheydo,sometimestheydon't.There'snosimpleanswer.

Inliningcanmakecodefasterbyeliminatingfunctioncalloverhead,orslowerbygeneratingtoomuchcode,causing
instructioncachemisses.Itmaymakeitlargerbyreplicatingallthatcalleecode,orsmallerbysavingtheinstructionsused
toimplementfunctioncalls.Itmayinflatethecodeofaninnermostloop,causingrepeatedcachemisses,oritmayimprove
thelocalityofreferenceintheloop,bycompilingallrelevantcodeatadjacentaddresses.Itmayalsobeirrelevantfor
performance,becauseyoursystemisnotCPUbound.

See?Toldyoutherewasnosimpleanswer.

FQA:However,thereisarelativelysimpleanswertothelegitimatequestion:"Whydoweneedthislanguagefeatureifits
effectisundefined?".SeethefirstFAQinthesection.There'salsoarelativelysimple&usefulrulesayingthatfunctions
whichhaveshortcodeand/oraretypicallycalledwithcompiletimeconstantargumentssothatmostoftheircodecomputes
aconstantaretypicallygoodcandidatesforinlining.Longfunctionsaretypicallyworsecandidatesforinlining,becausethe
functioncalloverheadisnegligiblecomparedtothethingsthefunctionsactuallydo,andthemainproblemwithinlining
largecodesizebecomesdominant.

It'susuallyagoodideatoonlyexplicitlyenabletheinliningofveryshortfunctions,andperformanceconsiderationsarenot
theonlyreason.InC++youhavetoplacethecodeinheaderfilestoenableinlining.Whiletheruntimeperformancemayor
maynotimprove,thecompiletimeperformanceisguaranteedtodrop.Whichmeanschangingcodebecomeshard,which
meansyou'lldoyourbesttonotchangeit,whichmeansyou'llleavewrongthingsunfixed.Anddebuggershandleinlined
codeprettypoorly(typicallyyoucan'tinspectthelocalvariablesofinlinedfunctionsorevenstepthroughtheirsourcecode
lines),sodebuggingtheoptimized(production)buildbecomesharder.Anddebuggingaspecial"debug"buildisnotalways
possible(somebugswon'treproduceinthatbuild),nottomentionthatyouhavetospendtimebuildingthosebinaries,too.

IfyourapplicationisnotCPUbound,youaren'tgettinganybenefitsfromusinganunsafelanguagelikeC++exceptforextra
qualitytimewiththedebugger.

http://yosefk.com/c++fqa/fqa.html 20/112
2/26/2015 C++ Frequently Questioned Answers

[9.4]Howcaninlinefunctionshelpwiththetradeoffofsafetyvs.speed?
FAQ:"InstraightC"youcouldimplementencapsulationusingavoid*,sothatuserscan'taccesstheunderlyingdata.
Instead,theusershavetocallfunctionswhichaccessthatdatabycastingthevoid*totherighttypefirst.

Notonlyisthistypeunsafeit'salsocostly,sincethesimplestaccessnowinvolvesafunctioncall.InC++youcanuse
inlineaccessorstoprivatedatasafe,fast.

FQA:TodayChasinlinefunctions(theFAQprobablydoesn'tconsiderthecurrentCstandard"straight",Iwonderwhy).
AFAIKtheywerebackportedfromC++togetherwithconstandotheruselessthings.Butit'sirrelevanttothequestion,
whichisaboutthecompletelywrongargumentthatinlineaccessorstoprivatefunctionsareaformof"highspeed
encapsulation".

First,thetalesaboutvoid*arewrongyoucanuseforwarddeclarationstoachievetheholygrailof(compiletime)type
safety.Second,agoodlanguageimplementationcaninlinethesmallCstyleaccessorsatlinktime.Third,privateprovides
littleencapsulationchangeaprivatememberandyouhavetorecompileallcodeusingtheclass.Fourth,mostfrequently
privatememberswithstraightforwardpublicaccessorsareajustverbosewaytoimplementapublicmember,since
changingtherepresentationisalmostimpossibleand/orhardlyuseful.

Andinthequiterarecaseswhereitispossibleanduseful,"properties"alanguagefacilityallowingtooverloadthe
obj.membersyntaxcouldsolvetheproblem,butC++doesn'thaveproperties.Oryoucouldrefactorthecodeautomatically
ifanythingcouldreliablyparseit.

IntheC++worldcodeisconsideredagoodthing,ofwhichthereshouldbeplenty.private: int _n; public: int n()


const { return _n; }isthusbetterthanint n;.ThequestionisdoyoulikelotsandlotsofC++codedoingpractically
nothing?

[9.5]WhyshouldIuseinlinefunctionsinsteadofplainold#definemacros?
FAQ:Becausemacrosareevil.Inparticular,whenamacroisexpanded,theparametersarenotevaluatedbeforethe
expansion,butcopied"asis"(theyareinterpretedascharactersequencesbythepreprocessor,notasC++expressions).
Therefore,ifaparameterisanexpressionwithasideeffect,suchasi++,andthemacromentionsitseveraltimes,the
macrowillexpandtobuggycode(forinstance,iwillgetincrementedmanytimes).Orthegeneratedcodemaybeslow
(whenyouuseexpressionslikefunctionTakingAgesToCompute()asmacroarguments).

Besides,inlinefunctionschecktheargumenttypes.

FQA:Yeah,Cmacrosarenopicnic.Butseethatthingaboutargumenttypes?Howcanyouwriteaninlinefunction
computingthemaximalvalueoftwoarguments?Atemplateinlinefunction,yousay?Trythis:std::max(n,5)withshort n.

Andhowshouldfunctionargumentsbepassedbyvalueorbyreference?"Byvalue"maycauseextracopying,and"by
reference"mayslowdownthecodeduetoaliasingproblems,forcingthecompilertoactuallyspillvaluestomemoryinorder
topassthemtothecodeofaninlinedfunction!How'sthatfor"performancebenefits"?AnotherproblemCmacrosdon't
have.

Frequentlyinlinefunctionsarebetterthanmacros,though,becausetheproblemswithmacrosturnouttobemoresevere
inmanycases.Asusual,it'syouwhogetstheinterestingjobofchoosingbetweenduplicateC++facilities,eachflawedinits
ownuniqueway.

[9.6]Howdoyoutellthecompilertomakeanonmemberfunctioninline?
FAQ:Prependtheinlinekeywordtoitsprototype,andplacethecodeinaheaderfile,unlessit'sonlyusedinasingle.cpp
file,orelseyou'llgeterrorsabout"unresolvedexternals"fromthelinker.

FQA:TheFAQ'sdecisiontoavoidthediscussionofthereasonsleadingtotheserequirementsiswrong.Clearlypeoplewho
don'tunderstandtheunderlyingimplementationissueswon'tsurvivetolivethemiserablelifeofcompetentC++developers.
That'sbecauseinC++,theunderlyingstufftendstoclimboutofthebasementinrepeatedattemptstomakeyoutheone
lyingunderapileofhard,urgent,mindnumbinglowlevelproblems.

Therefore,theonlylegitimateexcusefortellingaboutatotallyweirdlanguagerequirementandnotexplainingwhyitexistsis
brevity.SeetheFAQ'slengthydiscussionabouttheperformanceofinlinefunctionsforaprettygoodevidencethatbrevityis
hardlythemotivationhere.

[9.7]Howdoyoutellthecompilertomakeamemberfunctioninline?
http://yosefk.com/c++fqa/fqa.html 21/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:Declarethefunctionintheclassasusual.Inthedefinition,addtheinlinekeywordtotheprototype.Thedefinition
mustbeinaheaderfile.

FQA:Yep,it'ssimilartononmemberfunctions.

[9.8]Isthereanotherwaytotellthecompilertomakeamemberfunction
inline?

FAQ:Yes,bywritingitscoderightinthebodyoftheclass,insteadofonlywritingthedeclarationthere,anddefiningit
outsideoftheclass.Thisway,youdon'tevenhavetousetheinlinekeyword.

It'seasierwhenyouwriteclasses,butharderwhenyoureadthem,becausetheinterfaceismixedwiththeimplementation.
Rememberthe"reuseorientedworld"?Thinkaboutthewelfareofthemany,manyusersofyourclass!

FQA:Whatpopularlanguageforcesyoutowriteabareinterface("headerfile")andseparatelyanimplementation
containingalltheinformationintheinterface("sourcefiles")?Somehowallthoselanguageswhichonlymakeyoutypethe
interfaceoncearenotatallthathardtouse.Mayitbethatit'sbecausetheselanguagesareparsableandthereforeIDEs
candotheohsointerestingjobofextractingtheinterfacefromtheimplementationandthenyoucanusethingslikeclass
viewwindowstoinspectinterfaces?

Unlessyouusetemplatesandoperatoroverloadingandallthat,manyIDEsevenhaveachanceofworkingwithyourC++
code.Sowritinginlinefunctionsinsideclassdefinitionswon'treallyhurtyourusersafterall.EveniftherewerenoIDEs,you
shouldprobablyonlyinlineveryshortfunctions,withimplementationsasdescriptiveasacomment(isreturn _x;lessofa
documentationthan"//returnsthevalueofthexcoordinate"?).Ifthere'slotsof"implementationdetails"tohidefromtheeye
ofacasualobserver,inliningismostlikelyabadideaanyway.

[9.9]Withinlinememberfunctionsthataredefinedoutsidetheclass,isit
besttoputtheinlinekeywordnexttothedeclarationwithintheclassbody,
nexttothedefinitionoutsidetheclassbody,orboth?
FAQ:The"bestpractice"istoonlyuseitinthedefinitionoutsideoftheclass.Blah,blah,blah,arguestheFAQpassionately
abouttheissue."Observablesemantics","practicalstandpoint",blah,blah,blah.

FQA:Programmerstypicallyhaveagoodabilitytokeepmanydetailsintheirheads.Sogoodthatmanydon'trealizethat
thisabilityisfinite.Ifyoulitteryourbrainwithidiotic"bestpractices"whichdon'tevenaffecttheobservablesemanticsof
code,youdoitattheexpenseofnotthinkingaboutsomethingelsewhenyouwritecode."Somethingelse"mayinclude
reallyimportantthings,likethepurposeandthemeaningofthecode.

Ifyoudon'tcareaboutthissortofdiscussions,andyoufindyourselfunderanattackof"softwareprofessionals"buzzing
buzzwordsaboutyour"badpractices",sendthemalinktothispagetodistractthem,andusethetimegainedbythe
distractiontogooutandbuyabuzzertotalkbacktothem.

References
ThispageisaboutC++referencesaduplicatelanguagefeatureintroducedinordertosupportotherduplicatefeatures.

[8.1]Whatisareference?
[8.2]Whathappensifyouassigntoareference?
[8.3]Whathappensifyoureturnareference?
[8.4]Whatdoesobject.method1().method2()mean?
[8.5]Howcanyoureseatareferencetomakeitrefertoadifferentobject?
[8.6]WhenshouldIusereferences,andwhenshouldIusepointers?
[8.7]Whatisahandletoanobject?Isitapointer?Isitareference?Isitapointertoapointer?Whatisit?

[8.1]Whatisareference?
FAQ:It'sanaliasforanobjectanothernamebywhichitcanbecalled.Theimplementationisfrequentlyidenticaltothatof
pointers.Butdon'tthinkofreferencesaspointersareferenceistheobject.

FQA:AC++referenceislikeaC++pointerexceptforthefollowingdifferences:

http://yosefk.com/c++fqa/fqa.html 22/112
2/26/2015 C++ Frequently Questioned Answers
Youuseitasifitwereavalue:ref.member,notptr->member,etc.(inthissenserefbehaveslike(*ptr)).
Itmustbeinitializedtopointtoanobjectotherwise,thecodewon'tcompile.
Aftertheinitialization,youcan'tmakeitpointtoanotherobject.
Youcan'ttaketheaddressofareferencelikeyoucanwithpointers(formingapointertoapointer).
There'sno"referencearithmetics"(butyoucantaketheaddressofanobjectpointedbyareferenceanddopointer
arithmeticsonitasin&obj + 5).

Strangephraseslike"areferenceIStheobject"areusedquitefrequentlyintheC++community.Suchclaimsareonlyuseful
tohidethefactthatC++pointers&referencesaresosimilarthathavingbothinthelanguageisanunnecessary
complication.Inothercontexts,theclaimsaresimplyfalse.Forexample,awideclassofbugscomesfromaccessing
danglingreferencesreferencestoobjectswhichwerealreadydestroyed.Ifareferenceistheobject,orjustanothername
forit,howcanthathappen?Namesofdestroyedobjectsareinaccessibleittakesapreviouslyassignedpointertoaccess
adestroyedobject(C++alsobreaksthatruleyoucanaccessadestroyedglobalobjectbyitsnamefromadestructorof
anotherglobalobject,butthat'sadifferentcanofworms).

[8.2]Whathappensifyouassigntoareference?
FAQ:Areferenceistheobject,soofcourseyouassigntothereferentobject.

FQA:Whichmeansthatyoucan'tunderstandtheeffectofastatementassimpleasa=b;withoutknowingwhetheraisa
referenceornot.Anicefeaturecomplementarytoreferences(whichmakeyouwonderwhat"a"means)isoperator
overloading(whichmakesyouwonderwhat"="means).BecarefulasyouworkyourwaythroughaquagmireofC++code.

[8.3]Whathappensifyoureturnareference?
FAQ:Youcanassigntothereturnvalueofafunction.Thisisusefulforoperatoroverloading,asinarray[index] = value;
wherearrayisanobjectofaclasswithoverloadedoperator[]returningareference.

FQA:Exactlyandthat'swhyreferencesexist.

C++referencesareessentialforsupportingC++operatoroverloading.That'sbecauseChasnofacilityforassigningtothe
resultofafunctioncall(afunctioncanreturnapointerandyoucanassigntothepointedobject,butyouneedtousean
asteriskfordereferencingthepointer,whichisdifferentfromassigningwiththebuiltinoperator[]).Somemightsaythat
referencesserveamoregenericpurposetheymakepointerstoobjectsfeellikeobjects,butformostpurposesthatcanbe
achievedwithtypedef TStruct* T;.

Operatoroverloading,inturn,isuseful(thoughnotessential)fortemplatesaduplicatefacilitysolvingsomeoftheproblems
ofCmacrosandcreatingnew,frequentlymorecostlyandcomplicatedproblems.Forexample,operatoroverloadingisat
theheartofSTLuserdefinediteratorsmusthavetheinterfaceofaCpointerforinteroperabilitywithSTLalgorithms,which
canonlybeachievedwithoperatoroverloading.

Operatoroverloadingisalsousefulforprovidinguserdefinedcontainerssuchasstringsandvectors,duplicatingthe
functionalityofbuiltinstringsandarrays.

C++introducesduplicatefacilitiesinordertointroduceotherduplicatefacilities.Thenitsapologiststrytoconvinceeveryone
thattheoldfacilitiesare"evil".Thentheyexplainwhyremovingtheoldfacilitiesis"impractical".

[8.4]Whatdoesobject.method1().method2()mean?
FAQ:Thisiscalledmethodchaining.method1returnsareferencetoanobjectofaclasshavingmethod2.Thisisusedin
iostreamcout << a << endlismethodchaining(themethodisoperator<<).A"slick"waytousemethodchainingisto
simulate"namedparameters":a.setWidth(x).setHeight(y)).

FQA:It'sjustlikeobject->method1()->method2(),butwithreferencesinsteadofpointers.

Whilemethodchainingisnaturalinobjectorientedlanguages,it'sgoodtobeawareofproblemsrelatedtoit.Ata"high"
levelofdiscussionconcernedwithdesign,methodchainingcanbeasignofabstractionviolation(forexample,dowewant
theuserofobjecttobeabletodoarbitraryoperationswiththereturnvalueofmethod1?).Ata"low"levelofdiscussion
concernedwithcoding,method1hasnowaytoreportanerrorexceptforthrowinganexception,whichisnotalways
desirable.Inferringarulelike"methodchainingisevil"fromtheseissuesisprobablyanexaggeration,butanentiredesign
relyingonmethodchainingmayraisequestions.

Forexample,iostreamisalibraryforI/Oandformatting,andbothareafrequentsourceofruntimeerrors.Howshould
thoseerrorsbecheckedinstatementslikecout << a << b << c ...?Themethodchainingusediniostreamalsomakes

http://yosefk.com/c++fqa/fqa.html 23/112
2/26/2015 C++ Frequently Questioned Answers
formattingquitehardconsiderthe"I/Omanipulators".

The"implementation"ofnamedargumentsusingmethodchainingisaparticularlybadjoke.

[8.5]Howcanyoureseatareferencetomakeitrefertoadifferentobject?
FAQ:Youcan't.Thereferenceistheobject.

FQA:Youcan'tdoitinportableC++.Whilethereferenceisprobablyimplementedasapointerbyyourcompiler,there'sno
C++operatortogettheaddresswherethatpointerisstored.Inparticular,&refgivestheaddressofthereferentobject.

Onehastoworkaroundthisextremelyrarely,buttheneedcanemerge,especiallywhenthesourcecodeofpartsofa
programisunavailable.Ifthereferenceisstoredinsideanobject,youcanfigureoutitsoffsetbasedonthesizesofother
membersoftheclassofthehostingobject.Youcanthenmodifyitasifitwereapointer(asin*(T**)p = &myobj;).Thisis
severeabstractionviolation,anditisn'tportableC++.Makesureyouhavenootherwaytoachieveyourpurposebefore
doingthis.Inparticular,awayinvolvingpayingmoneytothevendorofthecodeunavailableinsourceformisfrequentlya
betterideathan"clever"hackslikethis.

[8.6]WhenshouldIusereferences,andwhenshouldIusepointers?
FAQ:Usereferencesunlessyoucan't,especiallyininterfaces.Inparticular,referencescan'tpointtoNULL,soyoucan'thave
a"sentinelreference".Cprogrammersmaydislikethefactthatyoucan'ttellwhetheramodifiedvalueislocalorareference
tosomethingelse.Butthisisaformofinformationhiding,whichisgoodbecauseyoushouldprograminthelanguageofa
problemratherthanthemachine.

FQA:Aswithmostduplicatefeatures,there'snogoodanswertothisquestion.

C++programmersusereferencestodenote"apointerwhichcan'tbenullandpointstoasingleobjectratherthananarray".
Usingpointersinthesecasesconfusespeoplebecausetheyassumethatpointersareusedintheothercases.Youdon't
wanttoconfusepeople,soyouusereferencestopassargumentstofunctions.Thenitturnsoutthatsometimesyouwantto
passanullpointertothosefunctions,andyouchangereferencestopointersthroughoutthecode.C++codeendsup
containingloadsofpointersandreferenceswithoutanapparentreasonforthechoicemadeineachparticularcase.

Ifyouchoosetouseareference,makesureyoudon'tneednullpointers,pointerarithmeticsorreseating.Youcan'thave
arraysofreferences,andyoucan'tstorereferencesincontainerclasses,becausethatwouldrequirehavinguninitialized
referencesand/orpointerstoreferences,andyoucan'thavethat.Memberreferencesinclasses/structsmustbeinitializedin
constructorsusingtheridiculouscolonsyntax.Thismakesithardertoreuseinitializationcodeindifferentconstructors,and
theproblempropagatestotheclassesusingyourclassasamembersinceyoucan'tprovideadefaultconstructor.There
are"smartpointers"(objectswithoverloaded->and*operators),butthereareno"smartreferences"(youcan'toverload
thedot),soyouwon'tbeabletoeasilyswitchtosomething"smart"laterbutthat'sprobablyrarelybadsincesmartpointers
arerarelygood.

Ifyouchoosetouseapointer,makesureyoudon'tconfuseotherC++programmers.Pointerstoobjectsofclasseswith
overloadedoperatorsleadtocodelike(*parr)[i],whichgetsannoying.Inmanycasesthecompilerwon'twarnyouwhena
pointerisleftuninitialized,whichmayleadtoerrorshardertodebugthansimplenullpointerdereferencing(nottomention
securityholesbutthere'senoughotherpossibilitiesfortheseinaC++programtomakethisaseparateissue).

Theseproblemsmeanthatinmanysituations,youmustchoosebetweentwoalmostequallybadalternatives.Whilemany
peoplesuccessfullyuseCpointersinC,itdoesn'tmeanthatalwayschoosingpointersoverreferencesinC++producesno
newproblemsC++hasfeatures,andC++programmershavehabitsinteractingbadlywithpointers.

Butthis,inturn,doesn'tinvalidatetheargument"pointersarebetterthanreferencesbecauseit'seasytoseewhethera
sideeffectislocalornot".Ofcoursethebehaviorofreferencesis"informationhiding"butisitthekindofinformationyou
wouldliketobehidden?Isn'tinformationhidingaboutmakingiteasytofigureoutwhataprogramdoes?Howdoeshiding
sideeffects,whichareaverybasiccrosscuttingsemanticalaspectofanyimperativelanguage,makethecodecloserto
"thelanguageoftheproblem"?

[8.7]Whatisahandletoanobject?Isitapointer?Isitareference?Isita
pointertoapointer?Whatisit?
FAQ:A"handle"issomethingidentifyingandgivingaccesstoanobject.Thetermismeanttobevague,omitting
implementationdetails(ahandlecanbeapointeroranindexintoanarrayoradatabasekey,etc.).Handlesareoften
encapsulatedinsmartpointerclasses.

http://yosefk.com/c++fqa/fqa.html 24/112
2/26/2015 C++ Frequently Questioned Answers
FQA:OneverycommonwaytoimplementhandlesinCreliesonincompletetypesandtypedefs:
typedef struct FooState* Foo;

Thedefinitionofstruct FooStateisincludedinthefilesimplementingFoo,butnotinthefilesusingit.Thisisprobablythe
closestthingto"encapsulation"youcangetinanunmanagedenvironment.Inparticular,ithasimportantadvantages
comparedtoC++classes:

WhenthedefinitionofFooStateischanged,callingcodedoesn'thavetoberecompiled(withC++classes,changinga
privatemembertriggersrecompilationofusercode).Thisshortenstherebuildcyclesandallowstoprovidestable
binaryinterfaces,simplifyingupgradesinmanyscenarios.
ThemoduledefiningFoocontrolstheallocationanddeallocationoftheobjects(withC++classes,theuseris
responsibleforallocationandmustchoosebetweenthestack,theglobaldata,thefreestoreandaggregationinside
anotherobject).Inparticular,FooStatemaycontainapointertothe"real"statestructure,allowingtransparent
reallocationofthesestructures.

TheChandletechniqueisalsowaybetterthanthe"smartpointer"tricksinC++.Inadditiontoreadabilityproblemsposedby
operatoroverloading(isitabarepointerorasmartpointer?),andthetediouscodinginvolved,smartpointersprovidelittle
encapsulation.That'sbecauseoverloadedoperator->mustreturneitherabarepointerorasmartpointer,whichmeansthat
thelastsmartpointermustreturnabarepointer,orthecompilationwillneverend(thelatteriseasytoachievewith
templateslikemanyothernotsousefulthings).SoyouendupreturningabarepointertoanobjectofaC++class,butina
waymoreconvolutedthanaverageC++code.

Whenimplementing"heavy"classes(unlike,forexample,simpleobjectsrepresentingvalueslikepointsina2dimensional
space),usingCstylehandlesistypicallymuchbetterthanpointersorreferencestoobjectsofC++classes.Whichisquite
surprisingconsideringthefactthatsupportingOOatthelanguagelevelisoneofthemainmotivationsbehindC++.

Constructors
Thissectionisaboutconstructors,whichcreateC++objects,aswellasalargenumberofproblems.

[10.1]What'sthedealwithconstructors?
[10.2]IsthereanydifferencebetweenList x;andList x();?
[10.3]Canoneconstructorofaclasscallanotherconstructorofthesameclasstoinitializethethisobject?
[10.4]IsthedefaultconstructorforFredalwaysFred::Fred()?
[10.5]WhichconstructorgetscalledwhenIcreateanarrayofFredobjects?
[10.6]Shouldmyconstructorsuse"initializationlists"or"assignment"?
[10.7]Shouldyouusethethispointerintheconstructor?
[10.8]Whatisthe"NamedConstructorIdiom"?
[10.9]Doesreturnbyvaluemeanextracopiesandextraoverhead?
[10.10]Whycan'tIinitializemystaticmemberdatainmyconstructor'sinitializationlist?
[10.11]Whyareclasseswithstaticdatamembersgettinglinkererrors?
[10.12]What'sthe"staticinitializationorderfiasco"?
[10.13]HowdoIpreventthe"staticinitializationorderfiasco"?
[10.14]Whydoesn'ttheconstructonfirstuseidiomuseastaticobjectinsteadofastaticpointer?
[10.15]HowdoIpreventthe"staticinitializationorderfiasco"formystaticdatamembers?
[10.16]DoIneedtoworryaboutthe"staticinitializationorderfiasco"forvariablesofbuiltin/intrinsictypes?
[10.17]HowcanIhandleaconstructorthatfails?
[10.18]Whatisthe"NamedParameterIdiom"?
[10.19]WhyamIgettinganerrorafterdeclaringaFooobjectviaFoo x(Bar())?

[10.1]What'sthedealwithconstructors?
FAQ:Aconstructorinitializesanobjectgivenachunkofmemoryhavingarbitrary(undefined)state,theway"initfunctions"
do.Itmayacquireresourcelikememory,files,etc."Ctor"isacommonabbreviation.

FQA:That'srightconstructorsinitializeobjects.Inparticular,constructorsdon'tallocatethechunkofmemoryusedfor
storingtheobject.Thisisdonebythecodecallingaconstructor.

Thecompilerthushastoknowthesizeofamemorychunkneededtostoreanobjectofaclass(thisisthevaluesubstituted
forsizeof(MyClass))ateachpointwheretheclassisused.Thatmeansknowingallmembers(public&private).Thisisa
keyreasonwhychangingtheprivatepartsofaC++classdefinitionrequiresrecompilationofallcallingcode,effectively
makingtheprivatemembersapartofthepublicinterface.

http://yosefk.com/c++fqa/fqa.html 25/112
2/26/2015 C++ Frequently Questioned Answers
ThisdesignofC++constructorsisextremelyimpracticalbecausethesmallestchangecantriggerthelargestrecompilation
cycle.ThiswouldbelessofaproblemifC++compiledfast,andiftherewasanautomaticwaytodetectthatcodewas
compiledwithanoutdatedclassdefinitionbutitdoesn't,andthereisn't.

ThisisoneofthemanyexampleswhereC++ignorespracticalconsiderationsinanattempttoachievetheoreticalperfection
("languagefeaturesshouldnever,everimposeanyperformancepenalty!").Comparethistotheapproachtakeninmost
objectorientedlanguages,whichnormallychoosetruedecouplingofinterface,sacrificingtheefficiencyofallocation.Some
oftheselanguagesprovidewaystooptimizetheallocationofpublicdata.Thisletsyouimproveperformancewhenyou
actuallyneedit,butwithouttheillusionof"encapsulation",andhaverealencapsulationintherestofyoursystem.

[10.2]IsthereanydifferencebetweenList x;andList x();?


FAQ:Yes,andit'sabigone.ThefirststatementdeclaresanobjectoftypeList,theseconddeclaresafunctionreturningan
objectoftypeList.

FQA:Theresureisquiteasemanticdifference.Toobadit'snotaccompaniedbyanequallynoticeablesyntacticdifference.
Whichiswhythequestionbecameafrequentlyaskedone.

Theproblemisthatit'shardtotellC++constructorcallsfromC/C++functiondeclarations.Thecasesdiscussedhere
constructorswithoutargumentsarearelativelymoderatemanifestationofthisproblem.Allyouhavetodoismemorizea
stupidspecialcase:constructorcallslooklikefunctioncallsexceptwhentherearenoarguments,inwhichcase
parenthesesmustbeomitted.TherearetonsofweirdrulesintheC++grammar,andanotheronedoesn'tmakemuch
difference.

Butwhentherearearguments,thingsgetreallyhairy.ConsiderthestatementA f(B,C);thisoughttobeafunction
declaration.Why?BandCaresurelyclasses,lookatthecapitalletters.Um,wait,it'sjustanamingconvention.Whatifthey
areobjects?Thatmakesthestatementaconstructorcall.Let'slookupthedefinitionofBandC,thatshouldgiveusthe
answertoourquestion.

HaveyoueverlookedupC++definitions(manuallyorusingtoolssuchasIDEs)?Checkitout,it'sfun.Youcanbesureof
onething:templatespecializationonintegerparameterswhentheinstantiationusesthesizeofaclassdefinedusing
multipleinheritanceandvirtualfunctionsasaparametervaluedoesn'tmakedefinitionlookupeasy.

WhenyougetanincomprehensibleerrormessagefromyourC++compiler,besympathetic.ParsingC++isafullblown,
industrialstrengthnightmare.

[10.3]Canoneconstructorofaclasscallanotherconstructorofthesame
classtoinitializethethisobject?
FAQ:No.Butyoucanfactoroutthecommoncodeintoaprivatefunction.Insomecasesyoucanusedefaultparametersto
"merge"constructors.Callingplacementnewinsideaconstructorisverybad,althoughitcan"seem"todothejobinsome
cases.

FQA:Youcan'toneofthemanygoodreasonstoavoidconstructors.Andanyway,havingmorethanoneconstructormay
beproblematicforanotherreason:theymustallhavethesamename(thatoftheclass),soinfactyou'redealingwith
overloading,andC++overloadresolutionisahugecanofworms.

Ifyou'reOKwiththat,youcansurelyusetheFAQ'sadvicetofactoroutcommoncode,unlessyoufollowanotherFAQ's
advicetheonesuggestingtousetheuglycolonsyntaxforinitializingmembervariables.Youcan'tmovethesethingstoa
function.

Ifyou'reinamoodforbreakingrulesanddoingclevertricks,thismaybetherighttimetolookforarealproblemwheresuch
skillsarereallyneeded.BreakingC++rulesbycallingplacementnewisprobablyabadideanotbecauseC++rulesareany
good,butbecausetheyareprettybad(astonishinglyandinconsistentlycomplicated).Thisisnotthekindofrulesyoucan
getawaywithbreakingyourmazeofhacksisdoomedtocollapse,andthere'senoughweightinC++toburyyourentire
projectwhenthishappens.Andanyway,whyinvestenergyintoanartificialsyntacticproblemwhentherearesomanyreal
onesoutthere?

[10.4]IsthedefaultconstructorforFredalwaysFred::Fred()?
FAQ:No,thedefaultconstructoristheonethatcanbecalledwithoutargumentseitherbecauseittakesnoneorbecauseit
definesdefaultvaluesforthem.

FQA:Yep,theruleisthatthedefaultconstructoristheonethatcanbecalled"bydefault"thatis,whentheuserofaclass
http://yosefk.com/c++fqa/fqa.html 26/112
2/26/2015 C++ Frequently Questioned Answers
didn'tspecifyanyparameters.

Anotherneatthingaboutdefaultconstructorsisthattheygetgenerated"bydefault".Forexample,iftheauthorofclassFred
didn'twriteanyconstructorsforit,aC++compilerwillautomaticallygenerateadefaultconstructorforit.Youdon'tseea
Fred::Fred,butitstillexistsinvisibleC++functionsaregreatforreadabilityanddebugging.Thesamewillhappenwith
otherthings,forexamplethecopyconstructor.IfyouthinkyoucanuseC++andsimplyavoidthefeaturesyoudon'tlike,
you'reinforarudeawakening:theinvisiblecompilergeneratedstuffislethalwhenyourclassacquiresresources(most
frequentlymemory).Inforapennyinforapound:ifyouwanttowriteC++classes,youhavetolearnprettymuch
everythingaboutthem,andthere'splenty.

Where'sallthiscodegenerated?Atthecaller'sside,ofcourse.Togenerateitneartherestoftheclassdefinition,theC++
compilerwouldhavetoknowwherethatdefinitionis,andthere'snogoodwaytotell(itmaybescatteredacrossasmany
sourcefilesastheauthordamnpleases).C++isjustlikeCinthisrespectthere'snowaytonarrowthesearchrangefora
definitionofanentitybasedonitsnameand/ornamespaceitcanbeanywhereintheprogram.Inparticular,thismeansthat
thedefaultconstructorwillbeautomaticallygeneratedatallpointswhereaclassisused,fromscratchyetanotherreason
whyC++codecompilesslowly.

Andwhat'sneededinordertogeneratethiscode?Thedefaultconstructorgeneratedbydefault(Ihopeyoufollow)callsthe
defaultconstructorsofallclassmembers(whichinturnmaytakeautogeneration).Addaprivatemember,andalldefault
constructorsgeneratedatthecallingcodemustberegeneratedyetanotherreasonwhyC++codemustberecompiled
frequently.

[10.5]WhichconstructorgetscalledwhenIcreateanarrayofFredobjects?
FAQ:Thedefaultconstructor.Ifthereisn'tany,yourcodewon'tcompile.Butifyouusestd::vector,youcancallany
constructor.Andyoushouldusestd::vectoranywaysincearraysareevil.Butsometimesyouneedthem.Inthatcase,you
caninitializeeachelementasinFred arr[2] = {Fred(3,4), Fred(3,4)};ifyouneedtocallconstructorsotherthanthe
default.Andfinallyyoucanuseplacementnewitwilltakeuglydeclarationsandcasts,youshouldbecarefultoalignthe
storageright(whichcan'tbedoneportably),andit'shardtomakethisexceptionsafe.Seehowevilthosearraysare?Use
std::vectoritgetsallthiscomplicatedstuffright.

FQA:Andallyoudidwasaskingasimplequestion!OK,let'sstartmakingourwaythroughthepileofrules,exceptions,
amendmentsandexcuses.

GivensyntaxlikeMyClass arr[5];thecompilerwillgeneratealoopcallingthedefaultconstructorofMyClass.Picksome
timewhenyouhaveabarfbaghandyandlookatthegeneratedassemblycode.Therearetwonicethings:sometimes
compilerswillemitaloopevenwhenit'sclearthatthedefaultconstructorhasnothingtodoandforautomaticallygenerated
defaultconstructors,you'llgetinlinecallstotheconstructorofeachmember(forthelatterthingyoudon'treallyneedan
array,asingleobjectwilldo).Bottomline:yourprogramgetsbiggerandbiggerandyoudon'tknowwhyyoudidn'tdo
anything.

Syntaxlikestd::vector<Fred> arr(5,Fred(3,4));getstranslatedto5callstothecopyconstructor(inpracticeintheory
otherthingscouldhappeningeneral,C++isexcellentintheory).ThisisfunctionallyequivalenttocallingFred(3,4)5times.
TheFAQdoesn'tmentionthatit'snormallyslowerthoughtypicallythenumbers3and4mustbefetchedfromthememory
allocatedforthecopiedobjectinsteadofbeingpassedinregistersorinlinedintotheassemblycode.

Ofcoursestd::vectorofafixedsizeknownatcompiletimeislessefficientthanabuiltinarrayanyway.Whichisone
reasontopreferabuiltinarray.InitializingsuchanarraywithmultipleFred(3,4)objectswillforceyoutoreplicatethe
initializer,andwillproducethebiggestpossibleinitializationcode.No,thecompilerisnotlikelytonoticethatyou'redoingthe
samethingoverandoveragain,itwillrepeatthesamecodeNtimes.Ontheotherhand,ifyourclassdoesnothinginthe
constructorbuthasan"initfunction",youcancallitinaloop.Anotherreasontoavoidconstructors.

ThehorrorstoriestheFAQtellsyouaboutplacementnewarealltrue.However,itdoesn'tmentionthatstd::vectoralways
allocatesmemoryonthefreestore.Andthere'snostandardcontaineryoucanuseforallocatingmemoryonthestack,for
example,soifyouwantone,you'llhavetowriteityourself.Andplacementnewisnecessarytomakesuchcontainerswork
withC++classeswithoutdefaultconstructors.Yetanotherreasontoavoidconstructors.

Anyway,saying"usestd::vectorbecauseitgetsthathorribleplacementnewstuffright"isalittlestrangeifyouconsiderthe
followingassumptions,oneofwhichmustapparentlyhold:

C++guyswantpeopletobuildtheirowncontainerclassesthenwhyisplacementnew,whichisrequiredtodothis
right,sohardtouse?
C++guysdon'twantpeopletobuildtheirowncontainerclassesthenwhyisn'tstd::vectorbuiltintothelanguage,so
thatthingslikeaggregateinitializationcouldworkwithit,andmaybewecouldgetridofthoseohsoevilarrays?

Maybeyoucan'texpectmoreconsistencyfromthepromotersofalanguagethanthereisinthatlanguageitself.
http://yosefk.com/c++fqa/fqa.html 27/112
2/26/2015 C++ Frequently Questioned Answers

[10.6]Shouldmyconstructorsuse"initializationlists"or"assignment"?
FAQ:Initializationliststhat'smoreefficient,exceptforbuiltintypes(withinitializers,youavoidtheconstructionofan
"empty"objectandtheoverheadofcleaningitupattheassignment).Andsomethingscan'tbeinitializedusingassignment,
likememberreferencesandconstmembersandthingswithoutdefaultconstructors.Soit'sbesttoalwaysuseinitialization
listsevenifyoudon'thavetoforthesakeof"symmetry".Thereareexceptionstothisrule.There'snoneedforan
exhaustivelistofthemsearchyourfeelings.

FQA:Therearegoodreasonstoavoidinitializationlists:

Youcan'twritemostkindsofcodeintheinitializationlistsnolocalvariablestoreuseresultsofcomputations,no
loops...Basicallythere'sC++andthere'sthisinitializerland,whereyoumustspeakacrippleddialectwithoutany
rewardfortheeffort.
Youcan'tmoveinitializerstoacommonfunctiontoreuseinitializationcode.
Ifyouwanttopassapointertoonemembertotheconstructorofanothermember,youmustmakesureitsconstructor
iscalledfirst,andtheseconstraintscangetcomplicated.
Tohelpyoumanagethoseconstraints,somecompilersproduceannoyingwarningswhentheorderofyourinitializers
differsfromtheorderinwhichyoudeclaretheclassmembers,evenwhenitdoesn'tmatter.
Theefficiencyargumentiswrongforaverycommoncasewhenthedefaultconstructorofamemberdoesnothing.
Typicallycompilersattributeallcodeininitializerliststothesamesourcecodelineforexample,theonewiththe
openingbraceoftheconstructorbody.Whenaprogramcrashesinsideaninitializer,youcan'teasilytellwhichoneitis
usingasymbolicdebugger.
Notthatit'sverydifferentfromtherestofC++,butthecolonsyntaxisjustplainugly.

Thetroublewithinitializationlists,likewithanyduplicatelanguagefeature,isthatyoucan'treallyavoidusingit.For
example,thereareclasseswithoutdefaultconstructors,orwithrelativelyheavyones.So"neveruseinitializationlists"isnot
averyusefulrule,andthebestanswer,asusual,isthatthere'snogoodanswer.

However,initializationlistsarereallylessthanuseful,soit'sprobablygoodtoavoidthemunlessyoucan't.Inparticular,
avoidingreferenceandconstmembersandhavinglightweightdefaultconstructorsinyourclassesmayhelp.

[10.7]Shouldyouusethethispointerintheconstructor?
FAQ:Somepeoplethinkyoucan'tsincetheobjectisnotfullyinitialized,butyoucanifyouknowtherules.Forexample,you
canalwaysaccessmembersinsidetheconstructorbody(aftertheopeningbrace).Butyoucanneveraccessmembersofa
derivedclassbycallingvirtualfunctions(thefunctioncallwillinvoketheimplementationoftheclassdefiningtheconstructor,
notthatofthederivedclass).Sometimesyoucanuseamembertoinitializeanothermemberinaninitializerlistand
sometimesyoucan'tyoumustknowtheorderinwhichmembersareinitialized.

FQA:That'srightallproblemsandquestionablescenarioscomefromtrickyC++things,likeinitializationlistsandvirtual
functioncallsfromconstructors.Ifyouavoidinitializationlistsanduseplainoldassignmentorinitializationfunctioncallsin
theconstructorbody,youcanbesureallmemberscanbeusedyouhaveoneproblemsolved.Useinitfunctionsinsteadof
constructorsandvirtualfunctioncallswillinvokefunctionsofthederivedclassanotherproblemsolved.

AnalternativetoavoidingthedarkcornersofC++istospendtimelearningthem.Forexample,youcanmemorizetherules
definingtheorderofinitialization,andrelyonthemheavilyinyourcode.Thatwaypeoplewhoneedtounderstandand/or
maintainyourcodewillhavetogetprettygoodatthesethings,too,soyouwon'tendupbeingtheonlyonearoundknowing
tonsofuselessobscurestuff.Ortheywillhavetoaskyou,whichincreasesyourweightintheorganization.Youwinbig
eitherway,atleastaslongasnobodychoosesthepathofphysicalaggressiontodealwiththeproblemsyoucreate.

[10.8]Whatisthe"NamedConstructorIdiom"?
FAQ:It'swhenyouhavestaticfunctions("namedconstructors")returningobjectsinyourclass.Forexample,thiswayyou
canhavetwo"constructors"returning2Dpointobjects:onegettingrectangularcoordinates(2floats),andanothergetting
polarcoordinates(also2floats).WithC++constructorsyoucouldn'tdoitbecausetheyallhavethesamename,sothat
wouldbeambiguousoverloading.Andthiscanbeasfastasregularconstructors!Andyoucanuseasimilartechniqueto
enforceanallocationpolicy,likehavingallobjectsallocatedwithnew.

FQA:Threecheers!ThisisalmostlikeCinitfunctionsastepintherightdirection.Namely,thiswaywedon'thave
overloadingproblems,andwecangetridofthepeskyseparationofallocationfrominitializationclientcodedoesn'treally
havetoknowaboutourprivatemembersanymore.

Theonlythinglefttodoistoditchthewholeclassthing,anduseCpointerstoincompletetypesasobjecthandlesthatway
wecanactuallymodifyprivatememberswithoutrecompilingthecallingcode.Orwecanusearealobjectoriented
http://yosefk.com/c++fqa/fqa.html 28/112
2/26/2015 C++ Frequently Questioned Answers
language,wheretheproblemdoesn'texistinthefirstplace.

[10.9]Doesreturnbyvaluemeanextracopiesandextraoverhead?
FAQ:"Notnecessarily".Atrulyexhausting,thoughnotnecessarilyexhaustivelistofexamplesfollows,withmanystories
about"virtuallyallcommercialgradecompilers"doingcleverthings.

FQA:Let'senumeratethepossibilitiesusingboringbinarylogic:

Youcareaboutperformance.
Youdon'tcareaboutperformance.

Inthefirstcase,"notnecessarily"isnotagoodanswerforyou.Youdon'twantyourcodetobelitteredwiththingslike
returnbyvalueandlaterwonderwhyyour"commercialgrade"compileremitshugeandslowcodeinsomeofthe
performancecriticalplaces.Ifperformanceisoneofyourgoals,you'rebetteroffwritingcodeinwaysmakingitaseasyas
possibletopredictperformance,withoutknowinganinfiniteamountofdetailsspecificforeachofthecompilersyouusefor
productioncode.Andifyouhaveexperiencewithoptimization,you'veprobablynoticedanotherthingmostC++compilers
workhardonoptimizingtheCsubset,butareprettydumbwhenitcomestoC++specificparts.Compilerwritersare
probablyhappyiftheycancorrectlyparseC++codeandsomehowlowerittoCandhavethebackendoptimizestuffatthe
Clevel.BasicallytogetperformanceyouneedC,becausethat'swhattoday'soptimizersarebestat,andyou'rewasting
timewithC++.

Ifyoudon'tcareaboutperformance,youarealsowastingtimeusingC++.Therearehordesofprogramminglanguages
designedformanagedenvironments,soyouwon'thaveproblemscomingfromundefinedbehaviorofallkinds.Andthevast
majorityoflanguagesarewaysimplerandmoreconsistentthanC++,soyou'llgetanotherhugeburdenoffyourback.

Ofcourseourboringbinarylogicfailstorepresentthedeveloperswhothinktheycareaboutperformance,althoughthey
haveaveryvagueideaabouttheactualperformanceoftheirprograms.ThosearethepeoplewhousethevonNeumann
model("youaccessmemoryusingpointerswhichareactuallyindexesofindividualbytes")tothinkaboutcomputers,and
callthis"thelowlevel".Theyaretypicallylessawareofthingslikeinstructioncaches(whichmakebigprogramsslow),SIMD
instructionsets(whichcangiveperformancegainswaybeyond"generic"templateimplementationsofnumerical
algorithms),assemblylanguageandoptimizersingeneral(forexample,howrestricthelpsoptimizationbutconstdoesn't).
Thesepeopleengageinlengthydiscussionsaboutcomplicatedhighleveloptimizations,theirultimategoalbeingvery
genericcodewhichcanbecompiledtoaveryefficientprogrambyaverysmartcompiler,whichwillneverexist.These
peoplearewelcometowasteasmuchtimethinkingaboutreturnbyvalueoptimizationsastheywish,aslongasitprevents
themfromcausingactualdamage.

[10.10]Whycan'tIinitializemystaticmemberdatainmyconstructor's
initializationlist?
FAQ:Becauseyoumustdefinesuchdataexplicitlyasinstatic MyClass::g_myNum = 5;.

FQA:Becauseit'smeaningless.staticmembersareglobalvariableswithrespecttoallocationandlifecycle,theonly
differenceisinthenamelookupandaccesscontrol.Sotheyareinstantiatedandinitializedonceperprogramrun.
Initializationlistsinitializethemembersofobjectswhichareinstantiatedwitheachobject,whichcanhappenmoreorless
timesthanonceperprogramrun.

Onepossiblereasonmakingthisquestionfrequentlyaskedisthatyoucanassigntostaticvariablesinthebodyofa
constructor,asing_numObjs++.PeopletryingtofollowtheadvicetousethecrippledC++subsetavailableintheinitialization
listsmightattempttotranslatethisstatementtoinitializerlikeg_numObjs(g_numObjs + 1)orsomething,whichdoesn'twork.

Youcanprobablylookatitbothways"initializersareusedtoinitializethingsinstantiatedperobject"and"thesubsetof
C++availableininitializationlistsmakesitimpossibletodoalmostanything".

[10.11]Whyareclasseswithstaticdatamembersgettinglinkererrors?
FAQ:Becauseyoumustdefinesuchdataexplicitlyasinstatic MyClass::g_myNum = 5;.

FQA:Beyondbeingannoying,thisisquiteweird.Atthefirstglanceitlooksreasonable:afterall,C++isjustathicklayerof
syntaxontopofC,butthebasicsimpletonmechanismsarethesame.Forinstance,definitionlookupisstilldoneusing
headerfilesholdingrandomdeclarationsandobjectfilesholdingarbitrarydefinitionseachfunctioncanbedeclared
anywhere(Ntimes)anddefinedanywhere(1time).

Sothecompilercan'tletyoudefinesomethingwhichbecomesaglobalvariableattheC/assemblylevelinaheaderfileasin
http://yosefk.com/c++fqa/fqa.html 29/112
2/26/2015 C++ Frequently Questioned Answers
static int g_myNum = 5;thatway,you'dgetmultipledefinitions(ateachfilewheretheclassdefinitionisincluded).
Consequently,theC++syntaxisdefinedinawayforcingyoutosolvethecompiler'sproblembychoosingasourcefileand
stuffingthedefinitionthere(mostfrequentlythechoiceistrivialsinceaclassisimplementedinasinglesourcefile,butthisis
aconvention,notarulethecompilercanusetosimplifydefinitionlookup).

Whilethisexplanationdoesn'tmakethesyntaxandtheweird"undefinedexternal"errorsanynicer,atleastitseemsto
makesense.UntilyourealizethattherearetonsofdefinitionscompiledtoC/assemblyglobalsinC++thatmustbeplacedat
headerfiles.Considervirtualfunctiontablesandtemplateclasses.Thesedefinitionsarecompiledoverandoveragaineach
timeaheaderfilegetsincluded,andthenthelinkermustthrowawayN1copiesandkeepone(ifthecopiesaredifferent
becauseofdifferentcompilersettingsand/orpreprocessorflags,it'syourproblemitwon'tbothertocheck).

ItturnsoutthatC++can'tbeimplementedontopofanylinkerthatsupportsCthelinkermustsupportthe"generateN
timesandthrowawayN1copies"feature(orisitadocumentedbug?),insteadofissuinga"multipledefinition"error.In
GNUlinkersthisiscalled"linkonce"orsomething.TosupportC++,youmustaddfeaturestothelinker.Toobadtheydidn't
thinkofaddingtypesafelinkage(checkingtheconsistencyofdefinitionsusedindifferentobjectfiles)whiletheywereatit.

Theconclusionisthatthereisnotechnicalreasonwhatsoever,eveninsidethetwistedC++universe,tomakethesyntax
harderfortheuserinthiscase.Ontheotherhand,there'snoreasontomakethesyntaxeasiereither.Thatwouldjust
introduceinconsistencywiththerestofthelanguage.

[10.12]What'sthe"staticinitializationorderfiasco"?
FAQ:Asubtle,frequentlymisunderstoodsourceoferrors,whicharehardtocatchbecausetheyoccurbeforemainiscalled.
Theerrorscanhappenwhentheconstructorofaglobalobjectdefinedinx.cppaccesses(directlyorindirectly)aglobal
objectdefinediny.cpp.Theorderofinitializationoftheseobjectsisundefined,soyou'llseetheproblemin50%ofthecases
(anerrormaybetriggeredbyarebuild)."It'sthatsimple".

FQA:Andit'sthatstupid.Justlookatthis:

C++doesn'tdefinetheorderofinitializationofglobalobjects.
C++letsyouwritecodethatdependsontheorderofinitializationofglobalobjects.
C++doesn'thaveamechanismtoautomaticallydetecttheseerrors,neitheratcompiletimenoratruntime.
C++doesn'tmaketheslightestefforttohelpyoudebugtheproblem(forexample,gofigureinwhichactualorderthe
objectswereinitialized).

Withmostduplicatelanguagefeatures,onecan'tsimplysay"avoidthenewbrokenC++features"becausethelanguage
workssohardtogetyouintroubleifyoudo.Butinthisparticularcaseit'sprobablyagoodrule.Considerthereasonsto
avoidinstantiatingglobalobjectswithnontrivialconstructors(onesthatdomorethannothing),andinsteaduseplainoldC
aggregateinitialization:

Youhavetoworryaboutthis"fiasco"business,whichisquitenasty.WithCinitializers,onceyoupassedcompilation
andlinkage,therearenoproblemsthelinkercreatesasnapshotoftheinitialstateofyourglobalvariables,andthere
arenofailuremodes.
Youhaveallthisinitializationcodebeforemain,withcorrespondingcleanupcodecalledaftermain.Whatifyouwantto
cleanupandreinitializethingswithoutexitingmain?Peoplecallinggetenvoraccessingthecommandlineusing
platformspecifictricksincodecalledbeforemainfurtherimprovethelifeofotherpeopleworkingontheproject.
Yourprogramcontainsahugebulkofslowinitializationcode.ACstatementlikePoint p={4,5};getstranslatedto8
bytesrepresentingtheintegers4and5intheexecutable.AC++statementlikePoint p(4,5);getstranslatedtocode
storing4and5top.Whatarethebenefitsexceptforgettinglargeprogramsstartingupslowly?

Somepeoplebelievethatyouneednontrivialglobalconstructors,orelseyou'llhavetomakeyourusercallaninitialization
functiontoworkwithyourmodule.Thefactisthattheexperiencedusersprefertoinitializemodulesexplicitlyratherthan
havingthemautonomouslykickingin,possiblycrashingtheprogrambecauseofdependencyissues,nottomentionprinting
messagesandpoppingupconfigurationdialogs.Alloftheseimplicitthingstendtobecomequiteexplicitonthedaywhen
youleastneedthemto.QuotingtheFAQ'sfavoriteexpression,justsayno.

[10.13]HowdoIpreventthe"staticinitializationorderfiasco"?
FAQ:Byusingthe"ConstructOnFirstUse"idiom,asin
MyClass& getMyObj()
{
static MyClass* p = new MyClass;
return *p;
}

http://yosefk.com/c++fqa/fqa.html 30/112
2/26/2015 C++ Frequently Questioned Answers
Thissolutionmay"leak".There'sanothersolutionworkingaroundthisproblem,butitcreatesotherproblems.

FQA:Bynotinstantiatingglobalobjectswithconstructorsdoingmorethannothing.Thatpreventsthisandotherkindsof
"fiasco".ThetechniqueintheFAQ,frequentlyreferredtoasanimplementationof"thesingletondesignpattern"(BTW,you
canputquoteswhereveryoulikeinthatone,forexamplethe"singleton""design""pattern"),hasthefollowingproblems:

AsmentionedbytheFAQ,itleaksmemoryandpossiblyotherresources(C++peoplelovetotalkabouthowmemory
is"justonekindofresource",overlookingthefactthatitaccountsfor99%of"resources"actuallyusedbyaprogram,
sospecial,"nongeneric"thingslikegarbagecollectionmaybeappropriatetomanageitbuttheysuddenlyforgetall
aboutitwhenitcomestothis"constructonfirstuse"business).Practitionersmayfinditintolerabletohavethese
memoryleaksreportedbytoolsdesignedtodetectleaks,eveniftheirplatformiscapableofdisposingthegarbageleft
byaprogramautomatically.Peopleinterestedinamoretheoreticaldiscussionmayenjoytherecommendationto
violatetheC++rulesregardingmemorymanagementfoundina"standardpractice".
Itisslow,nottomentionthreadsafety.WhenyouhaveaplainCglobalinitializedbyaplainCexplicitinitialization
function,accessingitisquiteeasy(functionargumentsmaybefastertofetch,ortheymaybenot).Inthiscase,you
callafunction(whichcanbeinlinedthatdoesn'tnecessarilyhelpthough)thatcontainsahiddenifstatement.You
don'tseeit?Well,howdoyouthinkthecleverfunctionmanagestoonlycallnewonce?There'saglobalboolean
(sometimescalled"guardvariable")whichitcheckseachtime.Toaccessaglobal,younowneedtoaccesstwo
globals.Ifyoufinditinteresting,youcanlistthesymbolsofyourprogram(usingaprogramlikenm),andthenfilterthe
outputusingaC++namedemangler(likec++filt).Youmayfindlotsof"guardvariableofsomething"kindofnames
there.

TheC++globalinitializationanddestructionsupportisbroken.Asusual,the"idiom"intheFAQ"solves"theproblemby
creatingworseproblems.

[10.14]Whydoesn'ttheconstructonfirstuseidiomuseastaticobject
insteadofastaticpointer?
FAQ:Itsolvesoneproblemandcreatesanotherproblem.Namely,youavoidtheresourceleak,butyourprogramcancrash
becausenowyouachieved"constructonfirstuse",butnot"destroyafterlastuse",sosomeonecanaccessadeadobject
(usingnewmeans"neverdestroy",whichisatleastguaranteedtobeafterlastuse).

Actuallythere'sathirdapproachsolvingbothproblems(initializationanddestructionorder),having"nontrivialcost".The
FAQauthorfeels"toolazyandbusy"toexplaingobuyhis"C++FAQBook"toreadaboutit.

FQA:TheFAQisrightthisvariant,knownas"theMeyers'singleton",isalsobroken.Andit'sprobablythehardesttowork
around,too.Atleastwiththenewvariantyoucandeletetheobjectwithdelete &getMyObj();increasinglyugly,butitmay
yieldaworking(thoughunmaintainable)program.Withthestaticvariabletechnique,C++recordsapointertothedestructor
insomeglobalarray,soyouwon'tbeabletocontroltheorderofdestruction(it'salwaystheorderofconstruction,reversed
andyoudidn'twanttocontroltheorderofconstruction,youwanteditto"justwork",right?).

AstootherapproachesIdohaveenoughenergyandsparetimetorepeatafreeadvice:useexplicitinitializationand
cleanupfunctions,andrealizethattheinitializationanddestructionsequencesarepartofthedesignofyourmodulesand
yourprogram.

Ifit'shardtogetoutofthestateofmindwhereyouthinkinitializationshouldsomehowworkoutbyitself,asopposedtothe
reallyinterestingthingsyourprogramdoesafterwards(the"steadystate"),maybeananalogywithhardwarecanhelp.Ina
simplifiedmodelofsynchronoushardwaredesign,youhavetwo"trees"ofsignals(basicallywires)reachingalmostevery
placeinyoursystem:theclock(whichsynchronizesthingsdoneatthesteadystate),andthereset(uponwhichallthe
initializationisconditioned).Acommonmilestoneinhardwaredesignisgettingtheresetright.Whenyoubuyhardware,a
largeportionofitisdevotedtoinitialization(whichiswhyyoucanrebootitanditentersareasonablestateyoucan'tdo
thatwithbiological"computers"likethehumanbrain).

Bytheway,Ididn'treadtheC++FAQbook(Ireallydon'thavetimeforaC++FQAbookatthemoment,sowhybother?).
ButIdidread"ModernC++Design",whichalsooffersasolution.SoifyoubuytheFAQbookandfindthethird"solution"
anditinvolveshavingyoursingletonsinstantiatedfromahairytemplatewithaglobaldatastructurekeeping"priorities"or
somesuchandregisteringatexitcallbackswhichcaninturncallatexitwhichdetectsdarkareasintheCandC++
standardsbecausenobodythoughtanyonewouldeverdothatifthat'sthethirdway,besurethatthecostisreally"non
trivial".

[10.15]HowdoIpreventthe"staticinitializationorderfiasco"formystatic
datamembers?
FAQ:Usingthesametechniquesjustdescribed,exceptforusingstaticmemberfunctionsinsteadofglobalfunctions.For
http://yosefk.com/c++fqa/fqa.html 31/112
2/26/2015 C++ Frequently Questioned Answers
somereasonalonglistofexamplesfollows,aswellasadiscussiononperformance.

FQA:There'snodifferencebetweenstaticdatamembersandglobalvariablesexceptfornamelookupandaccesscontrol.
Soyoucaneitherusethebroken&slowtechniquesfromtheFAQ,oryoucanavoidnontrivialconstructorsandlivehappily
everafter.

There'snopointinhavingseparatediscussionsonstaticdatamembersandplainglobalvariables.Well,exceptfor
mentioningthatstaticdatamembersareabrandnewC++feature,andit'sparticularlynicethatC++recommendstowrap
itsownsyntaxwithanotherlayerofitssyntaxfor"safety".AnalternativeapproachtosafetyistousezerolayersofC++
syntax.

[10.16]DoIneedtoworryaboutthe"staticinitializationorderfiasco"for
variablesofbuiltin/intrinsictypes?
FAQ:Yes,ifyouusefunctioncallstoinitializethemasinint g = f();thatwayfcanaccessg,oryoucanhaveother
dependencyproblems.

FQA:Exactlyandthiscodedoesn'tcompileinC.Weseemtohaveaprettyclearpicturehere,don'twe?Asaruleof
thumb,theanswertothemoregeneralversionofthequestion"DoIneedtoworrywhenIuseaC++featurenotavailable
inC?"isalso"Yes".

NotthatplainCisverysafe,mindyou.Ifyoudon'tneedtheperformance,youcanalwaysswitchtoasafer,higherlevel
language.ButatleastCdoesn'tpretendtobeveryhighlevel,andmakeslesspromisesitcan'tkeep(like"goahead,use
whatevercodeyouliketoinitializeglobalvariablesseehowhighlevelourlanguageis?").

[10.17]HowcanIhandleaconstructorthatfails?
FAQ:Throwanexception.

FQA:Right.

Q:Whatdoyoudowhenashipisonfire?
A:Drownit.Thefirewillstopimmediately.

Seriously,C++exceptionsarealeadingcandidateforthetitle"theworstwaytohandleruntimeerrorseverinvented".But
constructorscan'treturnvalues.Eventhoughtheydon'ttechnicallyreturnanobjecttheymerelyinitializeachunkof
memorytheyarepassed.SotheycouldreturnstatusinformationdespitetheC/C++limitationofatmostonereturnvalue
perfunction.Whichitselfhasnotechnicaljustification.Thisisyetanotherreasontoavoidconstructorsthatdomorethan
nothing.It'salsoyetanotherillustrationhowharditistouseonlysomeofC++featuresandavoidothers("wewantclasses,
butwedon'tneedexceptions"untilyouwanttohandleanerrorinaconstructor).

ItisalsonotablethattheC++standardlibrarydoesn'thandleerrorsinconstructors(oroverloadedoperators,whichposethe
sameproblem)usingexceptions(forexample,considerifstreamandofstream).

[10.18]Whatisthe"NamedParameterIdiom"?
FAQ:Ausefulapplicationofmethodchaining.ItworksaroundthefactthatC&C++don'thavekeywordarguments,andit
doesthatbetterthancombiningtheparametersinastringorabitmask.Itworkslikethis:
File f = OpenFile("language-abuse.txt")
.useWeirdLineBreakRules(true)
.writeLotsOfGoryDetails(true)
.averageNumberOfExcuses(ZILLION);
/* a sizable implementation with two classes and friends
and methods returning *this and what-not omitted */

Andifmethodcallsareinlined,there'snospeedoverhead(butthecodesizemay"slightly"increasebutthat'salong
story).

FQA:Let'shaveacloserlookatthisNamedParameterIdiocy.

TheimplementationintheFAQpushestheseparametersintoatemporarystructure,whichisnormallyslowerthan
argumentpassing.
Andthemultiplemethodcalls,inlinedornot,arenopicniceither.Compareassemblycodegeneratedbyprintfand
iostreamcallsifyoudoubt.Thiswayyoucancompareyournotionof"slightly"withthatusedbythedesignersofC++.
Allwaystoimplementthisrequiretheauthoroftheclasstowritealotofcodeultimatelydoingnothing.WhichisOK
http://yosefk.com/c++fqa/fqa.html 32/112
2/26/2015 C++ Frequently Questioned Answers
becauseintheory,eachclassiswrittenonceandusedthousandsoftimes.Inpracticemostclasseskeepchanging
foreverandareusedinacoupleofplaces.Whichdoesn'tmatteraslongasyouonlyuseC++intheorywhereit
belongs.
Butthatwouldbejustifiedtoanextentifitmadethingseasierfortheuser.Butitdoesn't.Tryreadingtheheaderfile
withtheclass OpenFileandfiguringouthowtoopenfiles.
AndnowthatwehavethisOpenFileclass,peoplewillstartstoringobjectsofthisclassandpassingthemaround.
Whichcouldbeagoodideainsomecases,exceptthattheclasshasastupidfunctionlikename,furtherenhancing
readability.
Orwecoulduseadifferentimplementation,chainingthemethodsofclass Fileandavoidingthesecondclass.But
thisway,wecan'tdetecterrorseasily,becausethere'snopointwhereweseealloftheparametersatonce,weget
themonebyone.

Thissyntacticsugarofthebitterkindraisestwoquestions.First,whydon'twehavekeywordargumentsinC++?Theyare
mucheasiertoimplementinacompilerthanvirtuallyanyfeatureC++addedtoC,andarewaymoreuseful,too.And
second,ifforsomereasonyouhavetoworkinC++,what'stheproblemwithacceptingthefactthatitdoesn'thavekeyword
arguments,andusingastructureofparametersinwayatleastmakingitclearthatyouuseastructureofparameters?For
example:
OpenFileParams params;
params.useNormalLineBreaks(true);
params.quitFiddlingWithSyntax(true);
File file; //trivial constructor
if(!file.open("grow-up.txt",params)) {
//handle errors without the "help" of C++ exceptions
}

Thisdoesn'tsolvetheproblemswithcodespeed&size,butatleastthecodeoftheclassandthecodeusingtheclassare
reasonablyreadableandwritable.Andthereseemtobenonewproblems,unlesssomeoneconsidersthefactthatourcode
isnowprettyclosetoCandwenolongerrelyonC++methodchainingaproblem.

AbusingC++syntaxinordertocoverupdeficienciesofC++syntax,thuscreatingrealproblemsinattemptstosolvenon
problems,isapopularhobbyamongC++professionals.Let'scheckifitmakessensebyimaginingthatsomeonespentthe
betterpartofthedaywritingallthiswrappercodedoingtrivialthings.Let'strytohelpthatsomeoneexplainwhatwas
accomplishedtosomeoneelse,andfurtherassumethattheothersomeonehasamindnotentirelyburiedinC++quirks."I
waswritingthis...Um,yousee,Iwasopeningafile...Iwrotethisinterfaceof2screensofcode...Andthen..."Sheesh,that's
embarrassing.

[10.19]WhyamIgettinganerrorafterdeclaringaFooobjectviaFoo
x(Bar())?

FAQ:Thishurts.Sitdown.

The"simple"explanation:thisdoesn'treallydeclareanobjectFoo x = Foo(Bar());does.Thecompleteexplanationfor
"thosecaringabouttheirprofessionalfuture":thisactuallydeclaresafunctionnamedxreturningaFoothesingleargument
ofthisxfunctionisoftype"afunctionwithnoargumentreturningaBar".

Don'tgetallexcitedaboutit.Don't"extrapolatefromtheobscuretothecommon".Don't"worshipconsistency".That'snot
"wise".TheFAQactuallysaysallthesequotedthings.

FQA:Thosewhousecomputerstodoanyusefulworkareprobablyimmunetobraincrippledsyntax,becausethereare
morepainfulthings,likebraincrippledsemantics.Sosittingdownisonlynecessaryifyoufinditcomfortable.Forsimilar
reasons,don'tworryaboutyourprofessionalfuturetoomuchifthislooksboringandstupidandyoudon'tfeellike
understandingit.Itreallyiswhatyouthinkitis,andprogrammingisnotsupposedtobeaboutthiskindofthing.Ifsomeone
rejectsyouinaninterviewbecauseyoudon'tknowtheanswertoaquestionlikethis,youareluckyyou'vejustescapeda
horribleworkingenvironment.

Anyway,ifforsomereasonyouarecurioustofindoutwhythishappens,itturnsouttheFAQhasnoanswers,itjust
presentsitasanarbitraryrule.Itdoesn'thelptounderstandanything.Thestatementisambiguousyoucanreaditbothas
aconstructorcallandadeclarationofapeculiarfunction.Howdoesthecompilerknow?Let'strytosee.

Apparentlythekeyproblemisthatinordertotellafunctiondeclarationfromaconstructorcall,youneedtoknowwhether
thethingsintheparenthesesareobjectsortypes.ThismakesparsingA f(B);nontrivial.Inourexample,thingsare
complicatedbythefactthatBar()itselfpresentstheverysameproblemisitafunctiondeclarationoraconstructorcall?
Worse,thistimethedarnthingacceptsnoarguments,soyoucan'tusethemtofigureitout.Well,C++hasanarbitraryrule
tohelpthecompiler(butnotnecessarilytheuser):thingswithemptyparenthesesarefunctiondeclarations,unlessthat's
entirelyimpossible(listofspecialcasesfollows).That'swhyA x();declaresafunctionbutA x;definesanobject.Andthat's
whyBar()isinterpretedasafunctiondeclaration,whichmeansthatit'sanargumenttype,notanobject,sothewhole
http://yosefk.com/c++fqa/fqa.html 33/112
2/26/2015 C++ Frequently Questioned Answers
statementisactuallyafunctiondeclaration.Ithink.

TheproblemwithFooandBaristhattheC++grammarisFUBAR.Inalanguagedesignedinamoreorderlyway(whichis
mostofthem),therearenosuchambiguities.Arelativelysimplewaytomakesuretherearenoneistouseaformal
grammarspecificationandfeedittoaprogramthatgeneratesaparserforthelanguage,checkingtheconsistencyofthe
grammarontheway.yacc/bisonisonematureprogramofthiskindthereareneweroneswithmorefeatures,whichcan
representmorecomplicatedgrammars(butAFAIKnogenerictooliscapableofrepresentingtheextremelycomplicated,
inconsistentandactuallyundecidableC++grammar).

ItcouldhelptheusersifthepeoplepromotingC++realizedthattheconsistencyofagrammarisnotsomethingyou
"worship",butatechnicalpropertywhichisfareasiertoachievethanitistodealwiththeconsequencesofnothavingit.
Thisexampleisjustonedropintheoceanofsuchproblems.ThecomplexityoftheC++grammarguaranteesthatcompiler
errormessageswillremaincryptic,debuggerswillstayignorant,andIDEswillbeunhelpfulcomparedtothoseavailablefor
otherlanguagesforever.

Destructors
DestructorsareoneofthemanypiecesofthepuzzlethatistheC++memorymanagement.

[11.1]What'sthedealwithdestructors?
[11.2]What'stheorderthatlocalobjectsaredestructed?
[11.3]What'stheorderthatobjectsinanarrayaredestructed?
[11.4]CanIoverloadthedestructorformyclass?
[11.5]ShouldIexplicitlycalladestructoronalocalvariable?
[11.6]WhatifIwantalocalto"die"beforetheclose}ofthescopeinwhichitwascreated?CanIcalladestructorona
localifIreallywantto?
[11.7]OK,OKalreadyIwon'texplicitlycallthedestructorofalocalbuthowdoIhandletheabovesituation?
[11.8]WhatifIcan'twrapthelocalinanartificialblock?
[11.9]ButcanIexplicitlycalladestructorifI'veallocatedmyobjectwithnew?
[11.10]Whatis"placementnew"andwhywouldIuseit?
[11.11]WhenIwriteadestructor,doIneedtoexplicitlycallthedestructorsformymemberobjects?
[11.12]WhenIwriteaderivedclass'sdestructor,doIneedtoexplicitlycallthedestructorformybaseclass?
[11.13]Shouldmydestructorthrowanexceptionwhenitdetectsaproblem?
[11.14]Isthereawaytoforcenewtoallocatememoryfromaspecificmemoryarea?

[11.1]What'sthedealwithdestructors?
FAQ:Adestructor,abbreviated"dtor",isa"you'reabouttodie"memberfunction.Itisusedtoreleaseresources,for
example,semaphores.Mostfrequentlytheresourceismemoryallocatedbynewthedestructorfreesitwithdelete.

FQA:Yep,C++hasnogarbagecollection,whichmakes"memory"amanuallymanaged"resource".DiehardC++
programmersfirmlybelievethatRAIIacquiringresourcesinconstructorsandreleasingthemindestructorsisthesilver
bulletforresourcemanagement.Theproblemwiththisapproachisthatmanyobjectscanpointtothesamepieceofdata,
butonlyoneofthemisthe"owner",andwhentheownerdies,itsdestructorpromptlyblowsthepieceofdatatoeven
smallerlittlepieces.

Themostcommonwayaroundthisiscopying.Forexample,youloadalargefilerepresentinga3DobjectmodeloranXML
documentorsomething.Youfindaninterestingleafonthe3DtreemodelorintheXMLtreeorwhatever.Nowyouwantto
releasethememoryofthewholemodelsothatyoucanfreesomespaceforprocessingthepart.Youneedtoeither
convincethemodelobjectthatitdoesn'townthestuffinyourleaf,oryouhavetocopythatstuff.Thelatteriswayeasier(try
toconvinceanownersuchasstd::listtoletacoupleofnodesgooutofitsjurisdiction).

Whichisonereasonthatcancausegarbagecollectiontooutperformmanualmemorymanagement.Butofcoursewith
garbagecollectionyou'llnevermasteryourdebuggingtoolstoanextentanywhereneartheexpertiseyou'llreachwith
manualmemorymanagement(you'llhave10timeslessbugstopracticeon).It'suptoyoutochoosetherighttradeoff.

Therearetwocommoncounterarguments:notallresourcesarememory,andnotallsystemscanaffordgarbagecollection.
Well,surelymorethan95%ofresourcesarememory,andsurelymorethan95%ofC++coderunsinsystemswhichcan
affordgarbagecollection.TheseargumentsareyetanotherevidencethatC++isabouttheory,notpractice.Andthe
resourceswhicharenotmemoryandmustbereleaseddeterministicallyusuallyaren'thandledverywellbeC++destructors
anyway.That'sbecauseaC++destructorcan'thandleerrors(ithasnoreturnvalueanditcan'tthrowexceptions).

[11.2]What'stheorderthatlocalobjectsaredestructed?
http://yosefk.com/c++fqa/fqa.html 34/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:Inreverseorderofconstructionthestuffdeclaredlastisdestroyedfirst.

FQA:Whichmakessense,butareyousureyouwanttowritecodethatdependsonthis?

[11.3]What'stheorderthatobjectsinanarrayaredestructed?
FAQ:Inreverseorderofconstructionthelastelementisdestroyedfirst.

FQA:Whichsortofmakessense,butyousurelydon'twanttowritecodethatdependsonthatone,doyou?

Bytheway,don'tforgettousedelete[],notjustdelete,tofreearraysallocatedwithnew[],otherwisethestupidthingwill
notbothertocheckthenumberofelementspointedbyyourpointerandsomeofyourdestructorswon'tgetcalled(actually,
intheoryitcouldbeworsethebehaviorisundefined).

[11.4]CanIoverloadthedestructorformyclass?
FAQ:No.Destructorsneverhaveparametersorreturnvalues.Andyou'renotsupposedtocalldestructorsexplicitly,soyou
couldn'tuseparametersorreturnvaluesanyway.

FQA:Whydoyouwanttooverloaddestructors?DoyoulikeC++overloading?Areyousure?Butthelackofreturnvaluesis
apitynowaytohandleerrors.Let'shopetheywon'thappen,shallwe?

[11.5]ShouldIexplicitlycalladestructoronalocalvariable?
FAQ:Don'tdothat!Thedestructorwillbecalledagainattheendofscope.Andthesecondcallwilldonastythings,like
crashingyourprogramorsomething.

FQA:Therearestandardquestionstoaskinthesecases,like"ifthissyntaxisneveruseful,whydoesitcompile"?Anyway,
youcancalladestructoronalocalvariable,butyouhavetomakesureyoucallaconstructorafterthatandbeforethe
objectgoesoutofscope.Forexample:
AMiserableFileClass file("f1.txt");
//use file... now we want to close it, but there's no close() method, so:
file.~AMiserableFileClass();
//open another file
new (&file) AMiserableFileClass("f2.txt");

AMiserableFileClassisamiserablefileclassbecauseithasnoclosemethod,soyoumightfeeltheneedtocloseitinthe
uglywayabove.Trytoavoidthis,becausemostpeoplewon'tunderstandit,andtheyshouldn't,becausetherearebetter
thingstodothanfiddlingwiththemanyuglybitsofC++.

[11.6]WhatifIwantalocalto"die"beforetheclose}ofthescopeinwhichit
wascreated?CanIcalladestructoronalocalifIreallywantto?
FAQ:No,no,no!SeethenextFAQforasimplesolution.Butdon'tcallthedestructor!

FQA:Ifyouevergetintothesituationofpromotinganespeciallydisgustingproduct,suchastheC++programming
language,therearebetterwaystohandleitthangetallexcited.Youcantryandfindalessdisgustingproducttocenteryour
moneymakingaround,oryoucanjustrelax.

"Don'tcallthedestructor".Therehastobesomereasonforthedestructorcalltocompile,doesn'tit?Perhapssharingitwith
uscouldhelpcalmdown.

[11.7]OK,OKalreadyIwon'texplicitlycallthedestructorofalocalbuthow
doIhandletheabovesituation?
FAQ:Nowyou'retalking!Here'satipyoucansimplysurroundtheobjectwithanartificialblock:
{
AMiserableFileClass file("f1.txt");
} //the file object dies here

FQA:Isthisuglycodesupposedtobebetterthantheuglycodecallingadestructorandthanaconstructor?Onalevel,this
versionismorecryptic(atleastit'seasytoseewhatgetscalledwheninthatotheruglypieceofcode).Butthetruthisthat
http://yosefk.com/c++fqa/fqa.html 35/112
2/26/2015 C++ Frequently Questioned Answers
formanyactualC++programmersthe"artificialblocks"(isn'tallcode"artificial"?)aremorereadable.

[11.8]WhatifIcan'twrapthelocalinanartificialblock?
FAQ:Ifyouabsolutelyhaveto,dosomethinglikeaddingaclosemethodtoAMiserableFileClasswhichclosesthefileinits
destructor.Soyoucanachievetheeffectofthedestructorcallwithoutcallingthedestructor.Whichisataboo,getit?

TheFAQalsopointsouthowharditistowriteaclosefunctionsothatthedestructordoesn'ttrytocloseaclosedfile.

FQA:IfyoucanchangeAMiserableFileClass,it'sbetterthanusinguglycodetoworkarounditsdeficiencies.Butwhere's
theFAQ'sbravenewreuseorientedworldnow?Whataboutallthoseclasseswithstableinterfacesyoucan'tchange?
Seriously,itcanhappenwithclassesnotavailableinsourceform.

Isincerelybelievethatthenotsoappetizing"callthedestructor,thencallaconstructor"methodislegalC++.Ifthisis
indeedso,Ifailtounderstandtheproblemwithmentioningitintheanswer.

Astotheproblemofhavingdestructorsandclosefunctionsrespecteachotheronewayaroundthisistoavoidnontrivial
constructorsanddestructorsandalwaysuseinitandclosefunctions.Next,youcanreplaceC++classeswiththeir
metaphysical"encapsulation"withforwarddeclaredCstructs,whichcanactuallyyieldstablebinaryinterfacesandsave
recompilation.Next,youcanreplaceC++withC(whereexecutiontimematters)orwithoneofthemanysane,safe
languages(wheredevelopmenttimematters).There,doesn'titfeelmuchbetternow?

[11.9]ButcanIexplicitlycalladestructorifI'veallocatedmyobjectwithnew?
FAQ:Youcan't,unlesstheobjectwasallocatedwithplacementnew.Objectscreatedbynewmustbedeleted,whichdoes
twothings(rememberthem):callsthedestructor,thenfreesthememory.

FQA:Translation:deleteisawaytoexplictlycalladestructor,butitalsodeallocatesthememory.Youcanalsocalla
destructorwithoutdeallocatingthememory.It'suglyanduselessinmostcases,butyoucandothat.

Questionslike"Whatexactlydoesdeletedo?"probablycrossthefinelineseparatingbetweenthequestionseveryone
claimingtoknowC++shouldbeabletoanswerandthequestionsidentifyingpeoplewithtoomuchC++relatedgarbagein
theirbrains.Peoplecanbequiteproductivebysimplycallingnewanddeletewithoutthinkingtoomuchaboutthetwosteps
involved,sonotknowingaboutthetwostepsisprobablynobigdeal.Themostinterestingthingaboutthetwostepsisthat
theideaofhavingthecodeusingtheclassmanagingthememoryofitsobjectsisthemainreasonC++codeisrecompiled
sofrequently.

[11.10]Whatis"placementnew"andwhywouldIuseit?
FAQ:Therearemanyusesforplacementnew.Forexample,youcanallocateanobjectinaparticularlocation,youcanpass
thepointertothislocationtoplacementnewlikethis:C* p = new(place) C(args);

Don'tusethisunlessyoureallycarewheretheobjectlives(say,youhaveamemorymappedhardwaredevicelikeatimer,
andyouwanttohaveaTimerobjectattheparticularlocation).

Beware!Itisyourjobtomakesurethattheaddresswhereyouallocatetheobjectisproperlyalignedandthatyouhave
enoughspacefortheobject.Youarealsoresponsibleforcallingthedestructorwithp->~C();.

FQA:Sizeisrelativelyeasytodealwithbecausewehavesizeof,alignmentcanbemorepainful.Here'sanadvice:ifyou
carewhereyourobjectsareallocated,don'tmakethemobjectsofclasseswithconstructorsanddestructorsandstuff.This
way,youcancreatememorypoolswithcodelikeC pool[N];,whichtakescareofalignmentand"typesafety".Butifthe
classChasaconstructor,it'sgoingtogetcalledNtimesbythisstatement(slowandstupid),andifyouwantsomeoneto
useplacementnewwiththepool,you'llhavetocallthedestructorsaftertheconstructorsfinishrunning(slow,stupidand
cryptic).Oryoucanusechar pool[N*sizeof(C);]withplatformspecificadditionstohandlealignment,andthenyouwon't
beabletoeasilyinspectthepoolinadebugger(theobjectpoolhasthewrongtype),etc.

Andyouhavetobeoutofyourmindtocallplacementnewwhenyoudealwithmemorymappedhardware.Doyourealize
thattheconstructorisgoingtodirectlymodifythestateofthehardware?Evenifyougetthisright(yes,therearewaystoget
thiswrong,tooboringtoenumeratehere),thisisoneveryunmaintainablewaytowritethiskindofcode.Ifyouthinkthat's
"intuitive",thinkagain.Whatistheconstructordoing"creating"thetimer?Comeon,it'shardware,itwasalreadyphysically
there.Oh,it"initializes"it?Sowhydon'tuseafunctionwith"init"initsnameinsteadofa"constructor"?

Youhaveenoughtroublethinkingaboutthesemanticsofthehardwareinterface,sowhywouldanyonewanttoaddthe
complexityofC++totheproblem?

http://yosefk.com/c++fqa/fqa.html 36/112
2/26/2015 C++ Frequently Questioned Answers
AtleasttheFAQhasfinallydisclosedthetopsecretinformationaboutexplicitlycallingdestructors.

[11.11]WhenIwriteadestructor,doIneedtoexplicitlycallthedestructors
formymemberobjects?
FAQ:No,theyarecalledimplicitlyinthereverseorderoftheirdeclarationintheclass.

FQA:Payattentiontothedetails.Ifyourmemberisapointertosomethingallocatedwithnew,thepointer'sdestructor,which
isapurelymetaphysicalentitydoingnothingphysicallyobservable,iscalled,butit'syourjobtocalldeleteonthepointer,
whichcallsthedestructorofthepointedobject.Thepointedobjectistechnicallynotamemberofyourclass(thepointeris).
Thedifferencebetweentheintuitivefeelingthat"it'spartoftheclass"andtheformaldefinitionoftheterm"member"isone
reasonmakingconstlessthanuseful(ischangingtheobjectpointedbyamember"changes"theobjectitselfornot?).

ExperiencedC++programmersfindthisnaturalsincetheC++approachtotheseissuesisrelativelyuniform.Ifyouhavethe
toughluckofusingC++alot,thispointisobvious(butyouwouldn'taskthequestioninthefirstplace).

There'saniftythingcalled"garbagecollection"that'sbeenaroundfornearlyhalfacentury.Theruntimesystem
automaticallyfiguresoutwhichobjectsarenotpointedbyanythingandcollectsthisgarbage.Checkitout,it'squitenice.

[11.12]WhenIwriteaderivedclass'sdestructor,doIneedtoexplicitlycall
thedestructorformybaseclass?
FAQ:No,thisisdoneimplicitly,inthereverseorderoftheappearanceoftheclassesintheinheritancelist(butvirtual
inheritancecomplicatesmatters),andafterthedestructionoftheclassmembers.

FQA:TheFAQsaysthatifsomeoneisrelyingonmorecomplicateddetailsofthefinalizationorder,you'llneedinformation
outsidethescopeoftheFAQ.Theremarkprobablyreferstousefulinformationlikelocationsofmentalinstitutionsanddrug
prescriptions.

Seriously,aUsenetlanguageFAQisalreadyaplacenormallyvisitedonlybylanguagelawyers.Ifyouneedmoreobscure
informationtogetyourjobdone,theonlylegitimatereasonisthatyou'rewritingaC++compiler.Ifthat'sthecase,andyou
feelmiserable,cheerupitcouldbeworse.Forexample,imaginethemiseryofthepeoplewho'lluseyourcompiler!

[11.13]Shouldmydestructorthrowanexceptionwhenitdetectsaproblem?
FAQ:THATISDANGEROUS!WhichisdiscussedinaFAQaboutexceptions.

FQA:Itshouldn't.Andyoucan'treturnanerrorcodeeither.However,onmanysystemsyoucansendanemailwiththe
word"BUMMER"toyoursupportemailaddress.

Ifyouwantyourdestructortodetectproblems,makeitaclosefunction.

[11.14]Isthereawaytoforcenewtoallocatememoryfromaspecificmemory
area?
FAQ:Oh,yessssss!Pools!Pools,pools,pools,pools,pools...

Pleaseforgivemethistime.Ican'tsummarizewhattheFAQissaying.It'salmostaslongasallthepreviousanswers.And
it'stotallyoutofcontrol.Ifyoufeellikeit,fastenyourseatbelt,grababarfbag,followthelinkandknockyourselfout.

FQA:Oh,nooooooo!Don'tdothat!

Iknowthatyoursystemhasmorethanonekindofmemoryand/oryouhaverealtimerequirementsandyoucan'tusea
traditionalmallocimplementation.Buttrustme,you'regoingtohatethedayyou'veheardaboutthosepools.Poolshave
arbitrarysizelimits(atmost20objectsofthis,atmost30objectsofthat...).Everybodyisgoingtohaveaparanoiaattack
andsetthelimitstohugevalues,andthenyou'reoutofmemory,andthenyoustartthinkingaboutthe"right"limits,andit
turnsoutthatit'sextremelyhardtofigurethatout,becauseseeminglyindependentmoduleshaverelatedmemory
requirements(say,theyhandlemutuallyexclusivesituationssoyou'dlikethemtousethesamememory,buthow?),and
thenyouneedsomehairylogictocomputethosevaluesonaperconfigurationbasis,whichmeansbuildingseveral
versionsoftheprogram,andmaybecreatingscriptsforcomputingthevaluesatbuildtime,andyou'regoingtohatetheday
you'veheardaboutthosepools.

http://yosefk.com/c++fqa/fqa.html 37/112
2/26/2015 C++ Frequently Questioned Answers
Ifyou'reabsolutelysureyoucan'tcreateasingleallocatormanagingyourmemory,atleastdon'tallocateobjectsofclasses
withconstructorsfrompools,useClikestructsinstead.Ifyourefusetogiveupandadmitthatyou'redoingaprettylowlevel
thingandinsteadwanttokeeppretendingthatyou're"programmingintheproblemdomain",andforsomereasonyouthink
C++classeshelpyouwiththatgoahead.ThepunishmentsforyourcrimearediscussedthroughouttheFQA.

Assignmentoperators
Thissectionisaboutoperator=.It'sratherstrangethatofallpossiblethings,peopleonly"frequentlyask"aboutself
assignment,butthosearetheonlyquestionslistedintheFAQ.

[12.1]Whatis"selfassignment"?
[12.2]WhyshouldIworryabout"selfassignment"?
[12.3]OK,OK,alreadyI'llhandleselfassignment.HowdoIdoit?

[12.1]Whatis"selfassignment"?
FAQ:It'sassigningtheobjecttoitself,directlyorindirectly.Forexample:
void f(C& x, C& y) { x=y; }
void g(C& x) { f(x,x); }

FQA:Thetrickypartisthattheassignmentoperatormaybeoverloaded,andyouareexpectedtooverloaditintheclasses
that"own"resources(mostfrequentlymemoryobtainedwithnew).Incidentally,theseareexactlythecaseswhenself
assignmentmayleadtotrouble,whichiswhywehavethenextquestion.WhichwillalsoshowthattheFAQ'sdefinitionof
"selfassignment"isunfortunatelytooconservative,as"self"isavagueconcept.

[12.2]WhyshouldIworryabout"selfassignment"?
FAQ:Ifyoudon't,youroperator=willprobablymisbehaveseverelyuponselfassignment:
YetAnotherSoCalledSmartPointer& YetAnotherSoCalledSmartPointer::operator=(const YetAnotherSoCalledSmartPointer& p)
{
delete _p;
_p = new TheThingPointedByTheSmartPointer(*p._p);
return *this;
}

Selfassignmentwillfirstdelete_p,andthendereferenceit,whichisnasty.Anditisallyourfaultyoushouldhavehandled
selfassignment!

FQA:Oh,soit'smyfault,isn'tit?Thenwhyisn'tthisquestionlistedinanyotherprogramminglanguageFAQontheplanet?
Imean,it'sthesamemeallthetime,it'sthelanguagesthataredifferent.Sowhydon'twelosethefeelingsofguiltand
checkwhatitisaboutC++thatcausestheproblem?

Mostlanguagesdaringtocallthemselves"objectoriented"havegarbagecollection,soyoudon'tspendyourtimewriting
stupidfunctionsfordeallocatingstuff,thencopyingstuff.Thesefunctionsareallalike,butwithC++yougettowritethiskind
ofcodeoverandoveragain.

C++doesn'thavegarbagecollection,soaproblemarisesifpeoplearecreatingallthoseobjects,howaretheygoingto
disposethem,especiallyiftheyoverloadoperatorsanddothingslikea+b+c,withoutevenkeepingthepointerstothe
temporaryobjectscreatedwhensubexpressionsareevaluated?TheC++answeristohavean"owner"objectforeach
chunkofallocatedmemory,andletoperator=andthedestructorworryaboutfreeingthememory.Themostcommon
manifestationofthisquiteuniquelanguagedesigndecisionisunnecessarycopying,whichhappenswhenobjectsare
passedtofunctionsorreturnedbyvalueor"cutout"fromlargerdatastructures.

Theselfassignmentproblemisanothermanifestationofthissamething.Ifobjectswerepassedbypointers/referencesand
garbagecollectedautomatically,selfassignment(settingthepointertothevalueofitself)wouldbeharmless.Andtheworst
partisthatthereareactuallymorecasesofselfassignmentthanx=x.Forexample,considerstd::vector::push_back().
Whatifsomeonepassesanobjectfromthevectoritself,asinv.push_back(v.back())?push_backmayneedtoallocatemore
memory,whichmaycauseittofreethebufferitalreadyuses,destroyingitsargument.Wheredoesthe"self"ofanobject
end?

Youhavetobereallysmarttogetallthosesmartpointerandcontainerclassesright.Toobadit'sstillworsethangood
containersbuiltintoalanguage.

http://yosefk.com/c++fqa/fqa.html 38/112
2/26/2015 C++ Frequently Questioned Answers

[12.3]OK,OK,alreadyI'llhandleselfassignment.HowdoIdoit?
FAQ:Byaddingatestlikeif(this==&that) { return *this; }orbycopyingthemembersoftheinputobjectbefore
deallocatingmembersofthis.

FQA:Thisavoidsthedestructionofyourfunctionargumentviaselfdestructioninoperator=.However,thereareother
caseswhenthatcanhappenconsiderstd::vector::push_back().

Whenperformanceismoreimportanttoyouthansimplicity&generality,onewaytodealwiththisfamilyofproblemsisto
documentthemandpassthemontotheuserofyourcode("itisillegaltopushanelementofavectorintothatvector,ifyou
needtodoit,copytheelementexplicitly").

Whensimplicity&generalityaremoreimportantthanperformance,youcanusealanguageautomaticallytracking
referencestoobjects,guaranteeingthatusedobjectswon'tgetdestroyed.

Operatoroverloading
Thissectionisaboutoperatoroverloadingawaytomakethecode"readable"aslongasthereaderdoesn'tcarewhatthe
codeactuallydoes.

[13.1]What'sthedealwithoperatoroverloading?
[13.2]Whatarethebenefitsofoperatoroverloading?
[13.3]Whataresomeexamplesofoperatoroverloading?
[13.4]Butoperatoroverloadingmakesmyclasslookuglyisn'titsupposedtomakemycodeclearer?
[13.5]Whatoperatorscan/cannotbeoverloaded?
[13.6]CanIoverloadoperator==soitletsmecomparetwochar[]usingastringcomparison?
[13.7]CanIcreateaoperator**for"tothepowerof"operations?
[13.8]Okay,thattellsmetheoperatorsIcanoverridewhichoperatorsshouldIoverride?
[13.9]Whataresomeguidelines/"rulesofthumb"foroverloadingoperators?
[13.10]HowdoIcreateasubscriptoperatorforaMatrixclass?
[13.11]Whyshouldn'tmyMatrixclass'sinterfacelooklikeanarrayofarray?
[13.12]Istilldon'tgetit.Whyshouldn'tmyMatrixclass'sinterfacelooklikeanarrayofarray?
[13.13]ShouldIdesignmyclassesfromtheoutside(interfacesfirst)orfromtheinside(datafirst)?
[13.14]HowcanIoverloadtheprefixandpostfixformsofoperators++and--?
[13.15]Whichismoreefficient:i++or++i?

[13.1]What'sthedealwithoperatoroverloading?
FAQ:Overloadedoperatorsprovidean"intuitiveinterface"fortheusersofyourclass.Theyalsoallowtemplatestowork
"equallywell"withclassesandbuiltintypes.

TheideaistocallfunctionsusingthesyntaxofC++operators.Suchfunctionscanbedefinedtoacceptparametersofuser
definedtypes,givingtheoperatorsuserdefinedmeaning.Forexample:
Matrix add(const Matrix& x, const Matrix& y);
Matrix operator+(const Matrix& x, const Matrix& y);
Matrix use_add(const Matrix& a, const Matrix& b, const Matrix& c)
{
return add(a,add(b,c));
}
Matrix use_plus(const Matrix& a, const Matrix& b, const Matrix& c)
{
return a + b + c;
}

FQA:Operatoroverloadingprovidesstrongsourcecodeencryption(thetimeneededtofigureoutwhata+bactuallymeans
isanexponentialfunctionofthenumberoftypes,implicitconversions,templatespecializationsandoverloadedoperator
versionsinvolved).

Itisalsoonewaytohavetemplatesmalfunctionequallymiserablywithuserdefinedandbuiltintypesif
BraindeadPseudoTypeSafeIterator<T>supportsthesyntax*pand++p,itcanbeusedjustlikethebuiltinT*inatemplate
"algorithm"likestd::for_each.However,itcouldalsoworkwithoutoperatoroverloadingforexample,youcanhavea
globalincrementfunctionforall"iterator"types,andimplementitforallpointertypesusingaglobaltemplatewrappercalling
++p.Whichmeansthatoperatoroverloadingispuresyntacticsugarevenifyoudon'tconsidertemplatesapileoftoxicwaste
you'dratherlivewithout.

http://yosefk.com/c++fqa/fqa.html 39/112
2/26/2015 C++ Frequently Questioned Answers
ThissyntacticsugarcanonlybeaddedtoalanguagelikeC++togetherwithmorethanagrainofsalt.Forexample,whatif
a+bfails?There'snogoodwaytoreturnanerrorstatus,becausethelanguageis"stronglytyped",soa+balwaysreturns
objectsofthesametype,forexample,aMatrix.There'snonatural"badmatrixvalue",andanywaythewholepointofa+bis
thatyoucanalsowritea+b+c.Ifyouneedtotesteachadditionwithanifstatement,a+bisnotmuchbetterthanadd(a,b).
Whataboutthrowinganexceptionuponerror?Notabadidea,inalanguagesupportingexceptions,asopposedtomerely
providingnonlocalgotousingthrow/try/catchsyntaxandhavingyoucareabout"exceptionsafety"ineachandeverybitof
code.

WhatabouttheallocationofourresultwheredoesthatMatrixlive?Ifit'sallocateddynamicallywithnewandreturnedby
reference,whoissupposedtocleanitup,inparticular,whokeepsthelistofalltemporariescreatedbya+b+c...?Butifit's
returnedbyvalue,thenthecopyconstructorisgoingtocopylotsofmatrices.Badifyoucareaboutperformance.Andifyou
don't,yousurelywouldn'tmindthesmallerruntimeoverheadofgarbagecollection(nottomentionruntimeboundary
checkingandotherkindsofsafetybelt),soyou'dprobablychooseadifferentlanguageinthefirstplace.

Operatoroverloadingisnotnecessarilyabadideaifyoucanactuallykeepthepromiseabout"readability".Todothat,you
needatleastthreethings:comprehensibleoverloadresolutionrules,easytouseexceptionsandeasytouseautomatic
memorymanagement.C++offersnoneofthose.

[13.2]Whatarethebenefitsofoperatoroverloading?
FAQ:Youcan"exploittheintuition"oftheusersofyourclasses.Theircodewillspeakinthelanguageoftheproblem
insteadofthelanguageofthemachine.They'lllearnfasterandmakelesserrors.

FQA:ThekeywordintheFAQ'sansweris"exploit".Yourintuitiontellsyouthata+bjustworksandinthe"problemdomain",
youareright.ButinC++,itdoesn'ttakethemachinetoolongtoraiseitsuglyironheadandstarttalkingtoyouinitsbarbaric
language,andithasallthemeanstomakeyoulisten.

Ifyouwanttoprogram"intheproblemdomain",usealanguagedesignedforthatproblemdomain.Prototypenumerical
algorithmsinMatlaborthelike,notinC++withsomematrixlibrary.DesignhardwareinVerilogorthelike,notSystemC
(whichisC++withsomehardwaredescriptionprimitiveslibrary).

Thenextbestalternativeistouseageneralpurposelanguagewhereoperatoroverloadingandothermetaprogramming
featuresactuallywork.Itistypicallyworse,butmaybecheaperspecialpurposetoolsareusedbylesspeoplethan
generalpurposeones,sothevendormustchargeeachuserahigherprice.Anditwillmakeyouhappyifyou'reoneofthose
peoplewhothinkthatthere'snothingaspecialpurposelanguagecandothatcan'tbedoneequallywellorbetterusingthe
wonderfulmetaprogrammingfacilitiesoftheawesomelanguageX(typicallywrong,butstrongprogrammerscanbevery
productiveoperatingunderthisassumptionunlessX=C++).

OperatoroverloadingandotherfeaturessuremakeC++equallyadaptabletoanyproblemdomain.Thisisachievedby
makingitthewrongtoolforeveryjob.

[13.3]Whataresomeexamplesofoperatoroverloading?
FAQ:Hereareafew(somereal,somehypothetical),therearemanymore.

str1 + str2concatenatesacoupleofstd::stringobjects.
NapoleonsBirthday++incrementsanobjectofclassDate.
a*bmultipliestwoNumbers.
a[i]accessesthei'thelementofauserdefinedArrayclassobject.
x = *pdereferencesa"smartpointer"whichactuallyrepresentsanaddressofadiskrecordthedereferencingseeks
tothatlocationonthediskandfetchestherecordintox.

FQA:C++operatoroverloadingisabadwaytoimplementallofthesethings.It'sanequallybadwaytoimplementalmost
everythingthatcomestomind.

Strings:ageneralpurposehighlevellanguageshouldhaveagoodbuiltinstringtype,becausetextprocessingisa
verycommontask.Inparticular,astringisanextremelycommontypeoffunctionparameter,soifyouhavenobuiltin
stringtype,eachkindofinterfacewilluseitsownkindofstring,andtheuserswillhavetospendmostoftheirtime
convertingbetweenstringtypes.Evenchar*andstd::string,whicharebothstandardstringtypes(therearelotsand
lotsofnonstandardones),haveinteractionsthatoperatoroverloadingfailstohide.Forexample,dir + "/" + file
compileswithstd::string dirandchar* file,butfailstocompilewithchar* dirandstd::string file,"exploiting"
theintuitionofusers.
Dates:whatdoesdate++mean?Doesitaddadayoraminuteorasecond?Thisquestionisespeciallyinterestingif
someonehadaseveremodelingtheuniverseusingtypesystemsattackanddefinedaTimeclass(incrementedby
seconds),aDateclass(incrementedbydays)andimplicitconversionsbetweenthem.Andifyouknowthatdatesare
http://yosefk.com/c++fqa/fqa.html 40/112
2/26/2015 C++ Frequently Questioned Answers
incrementedindayintervals,so1means"oneday",whynotjustuseintinsteadofDate?"Encapsulation"ofwhat
exactly?
Numbers:shouldbebuiltintoyourlanguage,oryoushouldstoppretendingthatyou're"programmingintheproblem
domain"(bothapproachesareperfectlylegitimate).Seethediscussionaboutstrings.
Arrays:shouldbebuiltintothelanguage,too.Andifyouuseatrickydatastructurebecauseresizablearraysbuiltinto
yourlanguagearenotgoodenough,makingitlooklikeanarrayisnotnecessarilyagoodidea.Forexample,people
mightwanttofindthedefinitionoftheoperator[]ina[i].Whatshouldtheydosearchfor"["?Oh,theyareusingan
IDEthatactuallyunderstands75%ofC++syntax?Nowwhatselecttheopeningbracketandaskforitsdefinition?
Neverworkedforme.
Smartpointerstodiskrecords:IwishallC++weeniesusedanoperatingsystemwhichimplementsfilesystemsusing
thisadvancedtechnique.Thisway,wheneverthe"dereferencing"wouldfail,eithertheerrorwouldn'tbereported,or
anexceptionwouldbemishandled,andtheweenieswouldlosetheirfiles,whichwouldbegoodforeverybody.

Basicallymostoperatoroverloadingusecasesfallintooneormoreofthefollowingcategories:

thethingcan'tbeimplementedwellunlessit'sbuiltintothelanguage(arrays,strings,numbers,"smartpointers"doing
thingslikereferencecounting)
thethingistrickyandshouldn'tbeconfusedwithbuiltintypes,sotheinterfaceshouldbedifferent("smartpointers"
doingthingslikediskaccess,complicateddatastructures)
thethingisobscureandshouldn'tbeimplementedatall(incrementingdatesbyunclearamountsoftime,transferring
outputstreamsintohexadecimalmodewithoutanoptiontorestorethepreviousmode)

However,itdoesn'tmeanthatoperatoroverloadingisneverusefulthatis,inthelanguagesthatcanactuallysupportit.

[13.4]Butoperatoroverloadingmakesmyclasslookuglyisn'titsupposed
tomakemycodeclearer?
FAQ:Noit'ssupposedtomakethecodeusingyourclassclearer!Forexample,youmayclaimthatT& operator[](int i)
islessreadablethanT& getAt(int i),butsurelyarr[i]ismorereadablethanarr.getAt(i)!

Youshouldrealizethat"inareuseorientedworld",usually(yes,theFAQsays"usually")manypeoplewilluseyourclass,
butonlyonewritesitscode(thatonepersonisyou).Thinkaboutthegoodofthemajorityyourusers!

FQA:Thoseguyslivinginthe"reuseoriented"worldsareverynoblecharacters.Toobadwe'restuckonplanetEarth,which
didn'tseemtohaveanyparticular"orientation"lasttimeIchecked.Onthisplanet,mostclassesyouwriteareused
exclusivelybyyourself,themajorityoftherestisusedbytwoorthreepeople,andonceinawhileyougettowriteaclassto
beusedbyNpeopleforN>3typicallyit'snotanarrayclass,butsomethingwithalittlebitlesstrivialfunctionality.Hereon
Earth,thisisconsideredgood:themoreinteractionbetweenpeopleandcomponents,themoreerrorstherearelikelytobe
(inserttheFAQ'sfavoritepseudobusinessorientedstatementsabout"defectrate"here).

Ofcoursethisdoesn'tmeanthattheotherclaimsmakeanysense.Forexample,usershavetofigureoutwhatyourclass
doesbeforetheyuseit,soitsinterfacemustbedefinedinareadableway,notjustlookreadablewhenused.Andyour
userswillprobablyneedtounderstandyourimplementation,too,becauseevenwhenyourcodenolongerhasbugs(this
mighttakeawhile),bugsinotherpiecesofcodemayendupcorruptingyourdata(thisisC++),sopeoplewillhaveto
inspectwhat'sleftofthatdatainordertofindtheoriginalerror.Soanunreadableand/orcomplicatedimplementationisnot
averygoodideaevenina"reuseoriented"world.

Lastbutnotleast,arr.getAt(i)isnotthatbad.

[13.5]Whatoperatorscan/cannotbeoverloaded?
FAQ:Mostcanbeoverloaded.Youcan'toverloadtheCoperators.and?:(andsizeof).Andyoucan'toverloadtheC++
operators::and.*.Youcanoverloadeverythingelse.

FQA:Thereareotherrestrictions,forexampletherecan'tbeaglobaloperator[]overloadyoucanonlyoverloadthis
operatorusingaclassmemberfunction.Whichisnotnecessarilybad.

[13.6]CanIoverloadoperator==soitletsmecomparetwochar[]usinga
stringcomparison?
FAQ:No,atleastoneparameterofanoverloadedoperatormustbeauserdefinedtype.

Butevenifyoucoulddoit,youshouldn'tyoushoulduseaclasslikestd::string.Arraysareevil!
http://yosefk.com/c++fqa/fqa.html 41/112
2/26/2015 C++ Frequently Questioned Answers
FQA:C++doesn'tletyoudoitforagoodreasonifyoucoulddoit,howwouldyoumakesurethatyourprogramis
compiledconsistentlyinthesensethatyouroperatoriscalledeverywhereinallcontextscallingoperator==onchar[]
arguments?Andwhatiftwosuchoperatorsaredefinedbytwodifferentmodules?

Unfortunately,theseproblemsarealmostequallyseverewithuserdefinedtypes.Forexample,std::mapdoesn'thavean
overloadedoperator<<printingittoanostream.Youcandefineone,butsocanI,andthenourlibrariesarelinkedtogether
intoasingleprogram.Theresultisunpredictable,rangingfromalinktimeerrortoaprogramprintingsomemapsusingyour
codeandsomewithmine.

Astothe"arraysareevil"mantrashowaboutchantingthemtotheauthorsoftheC++standardlibrarythatdefinedan
std::ifstreamconstructoracceptingconst char*,butnotstd::string?Andtheydidn'tdefineanoperator const char*in
std::string,either.std::ifstream in((std::string(dir) + "/" + file).c_str());.Givemeabreak.

AndwhydoestheFAQsay"astd::stringlikeclass",notjust"std::string"?Becauseifitdid,themajorityoftheaudience
stuckwithone(ormore)ofthemany,many"stringlike"classesdevelopedbeforeonewasaddedtotheC++standard
librarywouldlaughquitebitterly.

[13.7]CanIcreateaoperator**for"tothepowerof"operations?
FAQ:Youcan't.YoucanonlyoverloadoperatorsalreadyinC++,withoutchangingthenumberofarguments,the
associativityortheprecedence.Ifyouthinkit'swrong,considertheproblemofa**p,whichmeans"atimestheresultof
dereferencingp".Ifyoucoulddefineoperator**,you'dmakesuchexpressionsambiguous.

Andyouknowwhat?Operatoroverloadingisjustsyntacticsugar.Youcanalwaysdefineafunctioninstead.Whynot
overloadpow?

Oryoucouldoverloadoperator^,whichworksbuthasthewrongprecedenceandassociativity.

FQA:Sure,there'slotsofgrammarinC++,andmakinganunambiguousadditionisalmostimpossible.Thefactisthat,
informallyspeaking,there'safiniteamountof"good"syntaxyoucanhaveinyourlanguage.Thisisavalidargumentifyou
advocatedomainspecificlanguages(whichcanmaketheshort,simplesyntaxmaptostuffmostusefulinthatdomain),orif
youarguethat"languagesshouldhavenosyntax"(Lisp,SmalltalkandForthareexamplesoflanguageswithalmostno
syntax).However,it'sfunnywhenthisargumentisusedbytheC++FAQ.ItishardlycompatiblewiththeclaimsthatC++is
applicableeverywhere.Andthenthere'sthehugeamountofcompletelypointlesscomplicationsintheC++grammar(like
theconstructor/functiondeclarationpuzzle).

What'sthat?"Operatoroverloadingdoesn'tprovideanythingfundamental,it'sjustsyntacticsugar"?Nowyou'retalking.
Makethat"syntacticcyanide"andI'min.

Overloadpow?Cansomebodytellwhat'sthepointofallthisoverloading?Ifyouwantobfuscation,therearetoolsyoucan
usethatallowyoutokeepthesourceintheunobfuscatedform,whichmaybeveryhandyattimes.Besides,isn'tit
std::pow?AFAIKyouarenotallowedtoaddnamestothestdnamespace.Andifyouaddaglobalfunctionpow,you'lllose
theprecious"transparency"(std::pow(x,y)willnevercallyourversionofpow,onlypow(x,y)will),sowhat'sthepoint?

Theideatooverload"bitwiseexclusiveor"tomean"power"isjuststupid.Iwonderwheretheygettheseideas.It'sasif
someonedecidedtooverload"bitwiseleftshift"tomean"printtofile".Waitaminutetheydidthat,too...Ohwell.

[13.8]Okay,thattellsmetheoperatorsIcanoverridewhichoperators
shouldIoverride?
FAQ:Youwanttohelpyourusers,notconfusethem.Overloadoperatorsifitmakesthelifeofyouruserseasier.

FQA:Translation:don'toverloadC++operators.Whilewe'reatit,don'toverloadC++functions,either.C++overload
resolutionalwaysendsupconfusingusers.Andyoucan'tadderrorhandlingwithoutusingthehorribleC++exceptions,and
youcan'tallocateobjectssimplyandefficiently.

[13.9]Whataresomeguidelines/"rulesofthumb"foroverloading
operators?
FAQ:22(!!)"rulesofthumb"arelisted(actually20,2justsay"usecommonsense").Basically,therulesareaboutmaking
overloadedoperatorsbehavesimilarlytobuiltinoperatorsifyoudefine+,makeitassociativeanddon'tchangethe
parameters,etc.TheFAQwarnsthatthelistisnotexhaustive,norshoulditbeinterpretedasstrictrulesthatcan'thave
exceptions.

http://yosefk.com/c++fqa/fqa.html 42/112
2/26/2015 C++ Frequently Questioned Answers
FQA:Ruleofthumb#23:thingswhichhavesimplefunctionalitybutareveryhardtogetrightlinguisticallyshouldbeinthe
compiler.

Usecommonsense.Doyouhavethetimeforallthatthinkingwhenallyougetis"syntacticsugar"ofquestionabletaste?
Howaboutimplementingsomeuservisiblefunctionalityinstead?Notonlyisitwhatpeople(customers,employers,
colleagues,friends)ultimatelycareabout,it'salsomuchmorefun.

[13.10]HowdoIcreateasubscriptoperatorforaMatrixclass?
FAQ:Useoperator()whichcangettwoindexes,iandj.Don'tuseoperator[],whichcanonlygetoneindex.Acodelisting
follows.

FQA:Oh,dear.You'rewritingaMatrixclass.Mycondolences.

Onceyoudefineyoursubscriptoperator,bepreparedtoanswermanymorequestions.Howdoyouallocatetheresultof
operator+?HowdoyoumapexpressionslikeA+B*Ctooptimizedimplementationsofseveraloperations(forexample,
multiply_add)?WhyareyouwritingaMatrixclasswithoverloadedoperatorsinsteadofprototypingthecodeinMatlabor
thelikeandthenimplementingtheprototypeinCsothatitrunsfastandanybodycantellhowandwhyfromthecode,
insteadoffiguringouthowA+B*Cactuallyworks?

[13.11]Whyshouldn'tmyMatrixclass'sinterfacelooklikeanarrayofarray?
FAQ:The"arrayofarray"alternativeusesoperator[]toreturnanarrayobject,whichinturnhasanoperator[]returninga
singleelement.

Thisapproachislikelytobeworsebecauseofperformanceissueshavingtodowiththeoptimallayoutofthematrixin
memory,saystheFAQ.Ormaybeitsayssomethingelsesimilartoit.Ittalksalotabouttheissue.

FQA:Youcan'timplementthearrayofarraysyntaxwithasinglefunctioncall,becauseC++hasnooperator[][].Youneed
toreturnsometemporaryobjectwithanoperator[].

Thismeansextraworkforyou,becauseinsteadofwritingafunctionyouwriteawholeclassandafunctionreturningits
objects.Thisalsomeansextraworkfortheuserwhohastoreadalltheseinterfaces.Thisalsomeansextraworkforthe
compiler.ThechancesofacompilerfromplanetEarthtooptimizeoutthetemporaryobjectsareveryclosetozero.Which
meansit'salsoextraworkforthemachinerunningyourcode.

Andwhatdidyouachieve?"Syntacticsugar".ThisreasoningcanfrequentlybeusedtooptimizetheentireMatrixclasswith
allitsoverloadedoperatorsoutofyourschedule.Anditdoesn'tdependonperformancerelatedclaimsaboutmemorylayout
andstuff.

[13.12]Istilldon'tgetit.Whyshouldn'tmyMatrixclass'sinterfacelooklike
anarrayofarray?
FAQ:Becauseitmakescheckingtheargumentsorchangingthedatastructureharder.TheFAQthenexplainshowthiscan
stillbedone,andclaimsthatthecompilerwilloptimizethetemporariesout,butdoesn'tlikethefactthatit'salotofwork.

FQA:TheFQAprimarilydoesn'tlikethefactthatit'salotofwork.Butitwouldalsoliketopointoutthat:1.Thecompilerwill
probablynotoptimizethetemporariesout.2.Keyperformancecriticaldatastructuresareextremelycostlytochangeno
matterhowmuch"encapsulation"youuse,becauseoptimizationsdependontherepresentation.3.Checkingthearguments
isalwayshardwithoperatoroverloading,becausewhatwouldoperator()doonceanerrorwasfoundreturn1(how?),set
aglobalerrorflag,throwaC++exception?Alltheseoptionsarenotreallyacceptable.

Anyway,ifyouwanttowastesometimewithoutgettingusefulworkdone,therearewaystodoitthataremuchmorefun
thangettingoperator[][]sortofwork.AndthisiswheretheFAQandtheFQAagree.

[13.13]ShouldIdesignmyclassesfromtheoutside(interfacesfirst)orfrom
theinside(datafirst)?
FAQ:Outside,ofcourse.

AlongdiscussionabouttheaccessorsoneshouldhaveinaLinkedListclassfollows.Agroundbreakingconclusionis
reached:youshouldgiveaccessorstotheelementsofthelist,butnotthe"infrastructure"(say,thepointertothefirstnode).

http://yosefk.com/c++fqa/fqa.html 43/112
2/26/2015 C++ Frequently Questioned Answers
FQA:What?Whatdoesthisquestionhavetodowithoperatoroverloading?Andwhatdoesthekindofaccessorsyouwant
tohaveinyourclass(thefinalcode)havetodowiththewayyoudesignit(thinkbeforeyoucode)?

There'snosinglegoodwaytodesignclassesoranykindofsoftware.Sometimestheinterfacesaretheimportantthing,
sometimestheimplementation,andsometimesboth.Designingisakindofthinking.Sometimesyouneedtothinkaboutthe
datainordertofigureoutwhatkindofinterfacesareultimatelypossibletoimplementefficiently.Sometimesyoumustfigure
outtheinterfacefirsttomakesurethewholethingisactuallyuseful.Frequentlyyouhavetothinkaboutbothandpossibly
iterativelyrefinethem.

Theideathatimplementationsarenotimportant(becauseyoucanalwayschangethemorforotherreasons)mayonly
emergefromimplementingboringlytrivialthings,orfromdoingnothing(onewayofdoingnothinginthesoftwareindustryis
toobsessivelyseekthebestwaytospelltheiterationovertheelementsofalistforaliving).

Bytheway,theFAQmentions"abillionlineapp".C++doesn'tscaletomanylinesofcodeinthesensethatalarge
monolithicC++application(onewhereallcoderunsinasingleaddressspace)canhardlybemaintainable.Thisclaimmay
bemadeaboutotherlanguagesaswell,buttheproblemisespeciallyseverewithlanguagesassumingunmanaged
environments,whereabufferoverflowinmoduleAmaysilentlycorruptthedataofmoduleB.Ifyouhavelotsofunmanaged
code,breakingitintoprocessescansaveseveraltonsofyourbacon(ofcourseyouhavetobuildthesystemfromthe
beginningthatwayretrofittingitisextremelyexpensive).

[13.14]HowcanIoverloadtheprefixandpostfixformsofoperators++and--
?
FAQ:Likethis:
Iter& operator++ (); // ++p
Iter operator++ (int); // p++

Thepostfixversionshouldreturnsomethingequivalenttothecopyof*thismadebeforetheoperatorcall.

FQA:Sillysyntax,isn'tit?Ifyoudooverloadoperators,pleasereadandfollowalltheboringrulesabouttheirsyntaxand
semantics.Thiswillhelpyousoftentheblowonyourusers,orevenfallasleepandforgetaboutthewholethingifweare
lucky.

[13.15]Whichismoreefficient:i++or++i?
FAQ:It'sthesameforbuiltintypes.++imaybefasterforuserdefinedtypes,becausethere'snoneedtocreateacopythat
thecompilermayfailtooptimizeout.Mostlikelytheoverheadissmall,butwhynotpickthehabitofusing++i?

FQA:Oh,suddenlytheallmightycompilercan'toptimizeoutatemporary!Iactuallypickedthathabitatsomepoint.That
wasbeforeIpickedtheevenmoreusefulhabitofavoidingoverloadedC++operators.

ThereallyinterestingquestionsareabouttheperformanceofA+B*CcomparedtoD=B;D*=C;D+=Acomparedtoanoptimized
multiply_and_add_matrices(A,B,C)function.

Friends
Thequestionshereareaboutfrienddeclarations.Ashortanswertothemall:youprobablydon'tneedfrienddeclarations.

[14.1]Whatisafriend?
[14.2]Dofriendsviolateencapsulation?
[14.3]Whataresomeadvantages/disadvantagesofusingfriendfunctions?
[14.4]Whatdoesitmeanthat"friendshipisn'tinherited,transitive,orreciprocal"?
[14.5]Shouldmyclassdeclareamemberfunctionorafriendfunction?

[14.1]Whatisafriend?
FAQ:Aclasscandeclareotherclassesand/orfunctionsasfriends.Thedeclarationallowsthefriendstoaccessnonpublic
classmembersunaccessibletoothercodeoutsideoftheclass.

FQA:Inotherwords,friendrefinestheaccesscontrolprovidedbytheprivatekeyword.Whichmeansit'salmostuseless,
simplybecauseprivateisalmostuseless.Specifically,itfailstoprovideencapsulation,andthereforeislittlemorethana
comment.
http://yosefk.com/c++fqa/fqa.html 44/112
2/26/2015 C++ Frequently Questioned Answers
Ifyoudefineinterfacesbetweenmodulesdevelopedindependentlyandwanttheseinterfacestobestable,it'sbettertouse
Cfortheinterfacedefinitions,notC++.IfyouinsistonusingC++(forcingbothmodulestobebuiltwiththesametools),
relyingonprivatetoprovideencapsulationisabadidea,becausechangingprivatememberstriggersrecompilationofthe
clientcode.Youcanuseforwarddeclarationsand/orpureabstractclassestoprovideamorestableinterface.

Ifyouworkontheinternalinterfacesbetweenthedifferentclassesofamodule,andyou'restuckwithC++,usingprivateis
surelybetterthandefiningallmemberspublic.Thisway,someonecaneasilytellthatamemberisnotaccessedoutsideof
theclass,andclarityisgood.However,thereislittlereasontoobsesswiththefinedetailsofaccesscontrolintheinternal
interfaces.

Mostofthetime,thedistinctionbetweenprivateandpublicisgoodenoughtodescribewhatyouwant.Ifyoufeelastrong
urgetosplittightlycoupledfunctionsbetweenseveralclasses,youcandoitwithfriend,oryoucanmakethemembers
public.Ofcourseit'spossibletoargueforeveraboutthis("Butit'sbaddesigntoalloweveryonetoaccessthemembers!",
"Butit'sbaddesigntohavetightlycoupledclasses!").However,thesearesomeoftheinternalclassesofamodule,nothing
more,nothingless.Ifthemodulehasreasonablesize,theaccesscontrolisnotthatbigadeal.Ifthemoduleishuge,you
haveahugeproblemeitherway,especiallywithC++,whichcompilesforeveranddoesn'tlocalizethedamageofruntime
errors.

Therefore,friendistotallyuselessfortheexternalinterfacesandalmostuselessfortheinternalinterfaces.Sothereyou
are.

[14.2]Dofriendsviolateencapsulation?
FAQ:Onthecontrarytheyenhanceit.Ifusedproperly,ofcourse.

Forexample,youcanusethemtosplitcodeintotwoclassesandhavetheirdatainaccessibleforcodeinallotherclasses.
Oryoucanusethemas"asyntacticvariant"ofmemberfunctions.

Thinkofthefriendsaspartoftheclassinterfaceinsteadofsomethingoutsidetheclass.

FQA:Whatencapsulation?C++doesn'thaveencapsulation.Ithasaccesscontrol(codeoutsideofaclassusingprivate
membersofthisclasswillnotcompile),butithasneithercompiletimeencapsulation(stablebinaryinterfaces)norruntime
encapsulation(safememoryaccess).What'stheretoviolate?

ThecaseoftwoclasseswasdiscussedinthepreviousFAQthisargumentonlysoundsconvincingifyouthinkC++classes
areagoodwaytodefinetheimportant,stableinterfacesinyoursystem.

Astothe"syntacticvariant"business,it'sprobablyaboutoverloadedoperators.TheC++syntaxmakesitimpossibleto
defineoverloadedoperatorsasclassmembersunlessthefirstargumentisanobjectoftheclass.SinceC++uses
stream<<objtoprintthings,manyclassesdeclareafriend operator<<,forexample.Thisargumentisonlyinterestingifyou
thinkC++operatoroverloadingisanygood.

[14.3]Whataresomeadvantages/disadvantagesofusingfriendfunctions?
FAQ:Advantage:theyallowthedesignertochoosebetweenobj.func()andfunc(obj),which"lowersmaintenancecosts".

Disadvantage:theyrequiremorecodetoachievedynamicbinding.Nonmemberfunctionscan'tbevirtual,soifthe
designer'ssyntaxofchoiceisfunc(obj),anddynamicbindingisneeded,funcwillhavetodelegatetoaprotected virtual
memberwithobj.func().

FQA:Listencarefully,thisisanexcellentopportunitytolearnabouttheC++approachtowritingsoftware.Choosing
betweentwoequivalentsyntacticformsiscalled"design".Theavailabilityofmanyformsandthe"right"choicebetween
themisexpectedto"lowermaintenancecosts".Doesthismakeanysenseatall?Haveyouseenheadlinessuchas"An
engineerreplacedobj.func()withfunc(obj),profitsskyrocket"or"AresearcherwinstheTuringawardfordiscoveringa
newwaytoreplaceobj.func()withfunc(obj)"?

Andwhynotsayoutloudthattherealchoiceisbetweenobj<<streamandstream<<objorsomethinglikethis?Thisisreally
aboutoperatoroverloading,becausethat'swherethemember/globalfunctiondistinctionmattersmostsyntactically.Whynot
justsayobj.print(stream)insteadofshiftingstreamsbytheamountofbitsinanobjectorsomething?

[14.4]Whatdoesitmeanthat"friendshipisn'tinherited,transitive,or
reciprocal"?
FAQ:Itmeansthatclassesderivedfromafriendclassdon'tautomaticallybecomefriends(doyoutrustthekidsofyour
http://yosefk.com/c++fqa/fqa.html 45/112
2/26/2015 C++ Frequently Questioned Answers
friends?),afriendofafrienddoesn'tautomaticallybecomeafriend(doyoutrustthefriendsofyourfriends?),andthata
classdeclaringanotherclassas"friend"doesn'tautomaticallybecomeafriendofthatclass(doyoutrustanyonewhocalls
youafriend?).

FQA:Thereallifeanalogiesaretooscaryforadetaileddiscussion."Doyourfriendshaveaccesstoyourmembers"?

Onereasontoavoidfriendsisthattheonlypossiblebenefitisalittleextraclarity,butthisbenefitcanbedwarfedbythe
extraobfuscationnoteveryoneis(orshouldbe)100%surewhatfriendmeanswhenitcomestoclasshierarchiesand
stuff.

[14.5]Shouldmyclassdeclareamemberfunctionorafriendfunction?
FAQ:Useamemberfunctionunlessyoumustuseafriendfunction.Forexample,youmayneedfriendforoperator
overloading.

FQA:TheFAQsaysitatlast!See?Itwasaboutoperatoroverloadingalltheway.

TheFAQ'sadvicemaybefurthersimplifiedifweusetheobservationthatC++operatoroverloadingisjustapaininthe
neck.

Input/outputvia<iostream>and<cstdio>
Thissectionexplainsthebenefitsofiostreama"typesafe"I/Olibrary(whichdoesnotmeanitwillsavekeystrokeswhen
youtypesomecode).

[15.1]WhyshouldIuse<iostream>insteadofthetraditional<cstdio>?
[15.2]Whydoesmyprogramgointoaninfiniteloopwhensomeoneentersaninvalidinputcharacter?
[15.3]HowcanIgetstd::cintoskipinvalidinputcharacters?
[15.4]Howdoesthatfunkywhile (std::cin >> foo)syntaxwork?
[15.5]Whydoesmyinputseemtoprocesspasttheendoffile?
[15.6]Whyismyprogramignoringmyinputrequestafterthefirstiteration?
[15.7]ShouldIendmyoutputlineswithstd::endlor'\n'?
[15.8]HowcanIprovideprintingformyclass Fred?
[15.9]Butshouldn'tIalwaysuseaprintOn()methodratherthanafriendfunction?
[15.10]HowcanIprovideinputformyclass Fred?
[15.11]HowcanIprovideprintingforanentirehierarchyofclasses?
[15.12]HowcanIopenastreaminbinarymode?
[15.13]HowcanI"reopen"std::cinandstd::coutinbinarymode?
[15.14]HowcanIwrite/readobjectsofmyclassto/fromadatafile?
[15.15]HowcanIsendobjectsofmyclasstoanothercomputer(e.g.,viaasocket,TCP/IP,FTP,email,awirelesslink,
etc.)?
[15.16]Whycan'tIopenafileinadifferentdirectorysuchas"..\test.dat"?
[15.17]HowcanItell{ifakey,whichkey}waspressedbeforetheuserpressestheENTERkey?
[15.18]HowcanImakeitsokeyspressedbyusersarenotechoedonthescreen?
[15.19]HowcanImovethecursoraroundonthescreen?
[15.20]HowcanIclearthescreen?Istheresomethinglikeclrscr()?
[15.21]HowcanIchangethecolorsonthescreen?

[15.1]WhyshouldIuse<iostream>insteadofthetraditional<cstdio>?
FAQ:Therearefourreasons:

Increasetypesafety:withiostream,thecompilerknowsthetypesofthethingsyouprint.stdioonlyfiguresthemoutat
runtimefromtheformatstring.
Reducethenumberoferrors:withstdio,thetypesofobjectsyoupassmustbeconsistentwiththeformatstring
iostreamremovesthisredundancythereisnoformatstring,soyoucan'tmaketheseerrors.
Printingobjectsofuserdefinedtypes:withiostream,youcanoverloadtheoperators<<and>>tosupportnewtypes,
andtheoldcodewon'tbreak.stdiowon'tletyouextendtheformatstringsyntax,andthereseemstobenowayto
supportthiskindofthinginawayavoidingconflictsbetweendifferentextensions.
Printingtostreamsofuserdefinedtypes:youcanimplementyourownstreamclassesbyderivingfromthebase
classesprovidedbyiostream.FILE*cannotbeextendedbecause"it'snotarealclass".

FQA:WhyshouldIdothis,whyshouldIdothat,youask.Whatkindofmannersarethese?Dowhatyouaretold.

http://yosefk.com/c++fqa/fqa.html 46/112
2/26/2015 C++ Frequently Questioned Answers

AssignmentNumber1convertallyourevilprintf("0x%08xn", x)statementstothis:
std::cout << std::hex << std::setfill('0') << std::setw(8) << x << std::dec << std::endl;

Evenifyoucommittheenvironmentalcrimeofnamespacepollution,addingausing namespace stdandremovingthose


peskystd::,theverbosityisstillamazing.Thisachievementisnotaccidental.Itfollowsfromoneofthebasicflawsinthe
C++wayofthinking:the"everythingisatype"axiom.Forexample,hexhasaspecialtypewhichhexesstreams,andso
doeseveryotherstrangeobjectsenttocout.

TheFAQexplainswhythisthinkingisgoodforyou.Here'swhytheFAQiswrong:

Whyistypesafetyagoodthingherebecausewegainperformance?ThelasttimeIchecked,wedidn'treallygain
anyyourtypicaliostreamimplementationisslowerandbulkierthanyourtypicalstdioimplementation.Anyway,isn't
I/Othebottleneckhere?
Oh,nowIgetittypesafetyissupposedtohelpthecompilercatcherrors.Thisisveryimportantforpeoplewhonever
actuallylookatwhattheyprint.Theneedsofthispopulationsurelyjustifythe700Kofcrudthatgccgetstoparsewhen
compilingaC++"Hello,world"problem,aswellasmytimespentwaitingforittocompile.What'seasiertofix:arun
timeprintfproblemoracompiletimeiostreamproblem(withthecompilerhelpfullylistinghundredsofoverloadedleft
shiftoperators)?
Maybe"everythingisatype"isagoodthingbecauseitletsyouprintobjectsofuserdefinedtypes.Ifyoubelievethis,
concentratefor10secondsthisisyourchancetoachieveenlightenment.WhatonEarthpreventsyoufrom
printinguserdefinedobjectswithprintf?Youwriteahelperfunctionwhichgetsapointertoyourobjectandprints
it.Whileyou'reatit,givethefunctionsomespecialname,sothatyoudon'thavetoshovelthroughlistsofoverloads
anymore.What'sthat?It'sverbose,becausefunctioncallsareseparatestatements,unlikethefunkyleftshift
operators?Well,lookatasimplestatementprintinganintegeraboveifyoucareaboutverbosity.
Whataboutprintingtostreamsofuserdefinedtypes?Well,thisclaimisvalidinthesensethatthere'snowaytodefine
customFILE*,butithasnothingtodowiththefactthat"it'snotarealclass".A"realclass"isnotaverywelldefined
termtome,C++classeslookprettysurrealcomparedtoclassesdefinedinalmostanyotherlanguageI'veeverseen.
Anyway,stdiocouldprovidewaystodefinecustomFILE*,forinstancebyprovidingread,writeandothercallbacks.
Theauthorsjustdidn'tbother.Theabilitytodefinecustomstreamsdoesnotjustifytheproblemsofiostream,norisita
featureuniquetoiostream.Thisabilityisachievedin(relatively)saneOOways,(almost)inthewayit'sdoneinmany
languagessanerthanC++andI/Olibrariessanerthaniostream.

iostream.Theonlythingyou'llgainfromallthisextratypingisextralongbuildcyclesanderrormessagesandextralarge
programimage.Thisiswhatyougetwhenyoushiftafileobjectbyaninteger.

[15.2]Whydoesmyprogramgointoaninfiniteloopwhensomeoneenters
aninvalidinputcharacter?
FAQ:Probablyyoudidsomethinglikeint i; std::cin >> i;withoutcheckingforanerror.Fromnowon,allattemptsto
readstufffromstd::cinwon'tactuallyreadanything,becausethestreamhasenteredanerroneousstate.Presumably,you
wroteaprogramthatwillstillkeeptrying.Usesomethinglikewhile(std::cin >> i)instead.

FQA:Yep,that'siostream'swaytohandleinputerrors.Forsomereason,itdoesn'tthrowanexception(it'snotreallybad,
becausewhat'sreallybadisC++exceptions).Butitdoesn'treturnanerrorcode,either,becausetheoverloadedoperator
hastoreturnitsfirstargumentforthe"neat"operatorcallchainingtowork.Soithastosetanerrorbitthedreaded"zombie
object"patterntheFAQcondemnssoconvincingly.

Youcanthencheckforerrorsusingif(std::cin)orthelikebecausetheobjecthasoverloadedoperator void*,andvoid*
isconvertibletobool.Youcanalsocheckforendoffileconditionsthisway.Actuallyyoucancheckforerrororendoffile
conditions.Themoreoperatorcallsyouchain,thelessdetailsabouttheerrorcontextareleft.Simple,safe,efficientand
elegant.

Oh,andiostreamhasotherstatebits.Forexample,std::hextransfersittohexmode.Peoplefrequentlyforgettoundothe
effect,whichisespeciallyentertainingwhentheyprintnumberslike10,whichisasgoodadecimaltenasitisahexadecimal
sixteen.Well,ifyoufoundthebug(whichforsomereasonwentundetectedbythetypesafealmightyparanoidC++
compiler),youcanusestd::dectogetthestreambacktodecimalmode.Um,actually,ittransfersittodecimalmode,which
isnotnecessarily"back",becausewedon'tknowwhichmodeitwasinbeforeitwashexed.Thisgetsinterestingwhen
peopleprintnumbersanduserdefinedobjectsinthesamestatement,andcountontheirhexingtomaintainitseffectafter
theuserdefinedobjectisprinted.

[15.3]HowcanIgetstd::cintoskipinvalidinputcharacters?
FAQ:Here'sanexample:

http://yosefk.com/c++fqa/fqa.html 47/112
2/26/2015 C++ Frequently Questioned Answers
while ((std::cout << "Give me your credit card number now!!") && !(std::cin >> n)) {
std::cout << "Don't mess with me, I'm written in C++!!!";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

FQA:Oops,youforgottotestforendoffile.IfabraveuserhitsCtrl-Dorwhateverittakestoclosethestandardinputwith
thegiventerminal,yourprogramwillenteraninfiniteloop.Overloadedoperatorsanderrorhandlingarenotverycompatible.

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');speaksforitself.Youjustcan'tinventitifyour
"usecase"isyourselfgettinganyworkdone.

[15.4]Howdoesthatfunkywhile (std::cin >> foo)syntaxwork?


FAQ:istreamhasoverloadedoperator void*.Thecompilercallsthisoperatorinbooleancontexts(whenitexpectsa
condition,forexample),becausevoid*canbeconvertedtoaboolean.TheoperatorreturnsNULLwhenthere'snothingleftto
read,orwhenaformaterroroccurredpreviously.

FQA:There'snothing"funky"aboutit.Itisuglyandboring.It'salsoscarybecausemanypeoplethinkthisiswhat
programmingisallaboutusingcomplicatedsyntaxtodosimplethingswithoutevengettingthemright(howdoyoutell
endoffileconditionsfromformaterrors?).

Whyisitoperator void*,andnotoperator bool?Apparentlybecausethecompilerimplicitlyconvertsbooleanstonumbers


in"numericcontexts"(suchasfile1+file2),andwedon'twantthattocompile,dowe?

Butwait,there'smore!There'sanactualbookoutthere,called"ImperfectC++",arguingthatoperator void*isnottheway
togo,either.Becausethisway,delete filewouldcompile.Surelywedon'twantitto,dowe?Imean,thefactthatthe
statementiscompletelymoronicshouldn'tmatter.Moroneshavearighttogetanequalopportunityintheexcitingworldof
C++programminglet'scatchofalltheirerrorsatcompiletime.Evilpeoplespreadrumorsabouttheproblembeing
undecidable,butweshouldkeeptrying.

[15.5]Whydoesmyinputseemtoprocesspasttheendoffile?
FAQ:Becausethestreamdoesn'tknowthatyou'vereachedtheendoffileuntilyouactuallytrytoreadpasttheendoffile.
Forinstance,astreamobjectmayreadcharacterswhichareenteredinteractivelyusingakeyboard.Soit'simpossibletotell
whenit'sover.

FQA:That'sright,andhasnothingtodowithiostreamexceptthefactthatiostreamhandlesI/Oerrorsinthesillyway
discussedabove.

[15.6]Whyismyprogramignoringmyinputrequestafterthefirstiteration?
FAQ:Becausenondigitsareleftintheinputbuffer.Youcanignorethemusingcallslike
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

FQA:Doesn'tthefactthattherearesomanyquestionsaboutthehandlingofinputformatproblemsringabell?Thissilent
treatmentoferrorsiswrong.Stufflikeparsingisbetterhandledbylanguageswhichhavegoodsupportforexceptions(built
instringsandcontainershelp,too).Ifyouhavetolivewithoutexceptions,atleastthelibraryshouldtreaterrorsreasonably.
Theiostreaminterfaceofoperatorcallchainsmakeserrorhandlingasawkwardasitgets.

[15.7]ShouldIendmyoutputlineswithstd::endlor'\n'?
FAQ:Theformerhastheadditionalsideeffectofflushingtheoutputbuffer.Therefore,thelatterwillprobablyworkfaster.

FQA:Thelatterisalsoshorter,unlessyouhaveausing namespace std.Manypeopleprobablyaskthisquestionbecause


theythinkthatendlwillendthelinethewayit'snormallydoneatagivenplatform(say,emitCRLFonWindowsandLFon
Unix).Whenendlbehavesthatway,sodoes'\n'.Youcansuppressthisbehaviorwhenyouopenthefile(pass
ios::binarywithiostreamorthe"b"flagwithfopen).

[15.8]HowcanIprovideprintingformyclass Fred?
FAQ:Byaddingafriend std::ostream& operator<< (std::ostream& o, const Fred& fred);.Theoperatorcan'tbea
memberoftheclass,becauseweneedtheobjecttobethesecondargument,notthefirstone.

http://yosefk.com/c++fqa/fqa.html 48/112
2/26/2015 C++ Frequently Questioned Answers
FQA:Yeah,yeah,C++anditsstupidsyntax.Let'sforgetaboutitforamoment:therealproblemhereissemantical,andit
startsatthequestion"HowcanIprovideprintingformyclass?".Theformulationencouragestogiveananswerinthespirit
of"everythingisatype",andindeedthisisthekindofanswergivenbytheFAQ.Here'sthewaytoprintallobjectsofyour
class.

Butwasthatreallyyourquestion?Whatifyouwantmorethanasingleoutputformatforyourclass?Forinstance,youmight
wantatextualformatforpeopleandabinaryformatformachines.Ortherecouldbeseveraltextualformatsevenintegers
canbeprintedusingdifferentbases.Doyoureallywanttodevelopandmaintainthelayersofsyntaxneededtomakethings
likehexanddecsortofwork?Whynotjustdefinenamedfunctionsforprinting?

Thefriendthingisalsoquestionable.Withallduerespect,youmightwanttoprinttoseveraldifferentoutputchannels,
withoutcreatinganadapterclassderivedfromostream.Onesimplereasonforsuchhereticalbehaviorisperformance
ostreammaybetooslowforthingslikerealtimelogging.Whynotcreateaccessorstothedatayouwanttoprint,sothatall
thedifferentoutputmethodswon'tneedtobepartofyourclass,whichmaythenhaveastableinterface?Encapsulation?
You'vealreadymadeyourdatapubliconecanreaditbyprintingtoastringstream.Providingaccessorsviolates
obfuscation,notencapsulation.

Ifyouabandonthefriendpartandtheoperatorpart,theremainingpartoftheFAQ'sanswercreateaglobalfunction
acceptingsomekindofstreamobjectandanobjectofyourclassanddotheprintingtheremakesagoodadvice.In
particular,itmaybebetterthanamethodforthesamereasonsmakingitbetterthanafriend(however,unlikeafriend,a
methodmaybepolymorphic,whichmightbeuseful).

[15.9]Butshouldn'tIalwaysuseaprintOn()methodratherthanafriend
function?
FAQ:Not"always".Amethodmaybeusefulforaclasshierarchy,forexample,butinthatcaseitwouldnormallybe
protected,notpublic.

Somepeoplethinkfriendviolatesencapsulation,andthereforeprefertohavetheiroperator<<callapublicmethodofthe
class,eventhoughthere'snoclasshierarchy.Theirbasicassumptioniswrong,sotheyendupwritingextracodethat
doesn'tsolveanyrealproblemsandconfusespeople.

FQA:Justtomakethingsclear:aprintOn()methodissomethinglikevoid Fred::printOn(std::ostream& o) const.

TheFAQisrightabouttheimportantthing:creatingextralayersofcodedoingnothingbutdelegatingworktootherlayersof
codeisapeskyhabit.Manypeoplefeelthat"gooddesign"means"lotsofcode"or"lotsoflayers".Actually,thosearesome
ofthemeaningsof"baddesign".

ThefactthatfriendisreallyneededheretocompensateforsyntacticallimitationsofC++,aswellastheproblemswiththe
wholefriend operatorapproach,arediscussedinthepreviousFAQ.Theyarenotthemainthemehere.Themaintheme
hereisthemessagetothe"designers":listentothevoiceofC++overlordswhooriginallyinspiredyoutocreateNlayers
with0functionality,andstop.

[15.10]HowcanIprovideinputformyclass Fred?
FAQ:Byaddingafriend std::istream& operator>> (std::istream& i, Fred& fred);

FQA:Thisdefectivetechniqueissymmetricaltotheoperator<<thing,whichwasdiscussedabove.We'llusethisopportunity
tolookatsomeadvanceddefectsofthisapproach.Forbeginner'sdefects,gotwoFAQsback.

Thecomplicatedproblemscomefromthesamesourceasthesimpleproblems:theideathatforeachtype,wewantexactly
oneoutputfunctionlookinglikeabitshiftoperator.Therefore,tocreatecomplicatedproblems,we'llneedsomecomplicated
types.Luckily,C++comeswithoneofthemostcomplicatedtypesystemsinthesolarsystem(itselfanexampleofasimpler
system).

Considerstd::map.It'sstandard,andsoisiostream.Doesthismeanthattheoperatorsreadingandwritingthemarealso
standard?Ithinkyouknowtheanswer.Butnomatter:youcancreateatemplateoperatorprintingallkindsofmap.SocanI.
We'rebothhappy,unlesswehavetointegrateourcodeintoasingleprogramsometimelater.Webothusedthesame
intuitivenameoperator<<forourprintingfunctions.Normallywe'drenameoneofthetwo,butinthisspecialcase,thisis
reallygoingtobeuglyforinstance,othertemplateswillbreakbecausetheythinkeverythingcanbeprintedwith<<,and
eveniftherearen'tany,printMap(std::cout << "map: ", myMap) << std::endlistoouglyevenforseasonedC++
developers,whodohaveprettylowstandards.

Therealfunstartswhentwopeopleoverload(orspecializeorwhatevertheycallit)theoperatorsforspecialcasesoftypes
inconflictingways.Forinstance,Iknowhowtoprintstd::map<std::string,T>,andyouknowhowtoprintstd::map<T,int>.
http://yosefk.com/c++fqa/fqa.html 49/112
2/26/2015 C++ Frequently Questioned Answers
Thequestionis,whogetstoprintstd::map<std::string,int>?Thecompilerisintrouble,andwhenaC++compilerisin
trouble,itimmediatelyemptiesitsbowl,dumpinganice,large,stinkyerrormessagerightatourfaces.Happy,happy,joy,
joy,dearcolleague.

[15.11]HowcanIprovideprintingforanentirehierarchyofclasses?
FAQ:Youcancreateaprotected virtualmethodthateachclasswilloverridetodotheprinting,andcallitfromafriend
operator<<.

FQA:Fantastic,exceptfortheprotectedandthefriend operator<<part.Ofcourseyoucanuseaplainpublic virtual


methodinstead.

[15.12]HowcanIopenastreaminbinarymode?
FAQ:Openthestreamwiththestd::ios::binaryflag.Thatway,thestreamwillnottranslatebetween'\n'andthetarget
platformrepresentationoflinetermination,whichmaybedifferent(forinstance,WindowsusesCRLF).

FQA:Withfopen,passthe"b"characterintheoptionsstring.Thiswholeissueisprettyannoying,especiallyifyouworkwith
binaryfilesonasystemwhere'\n'isnotactuallytranslated,andforgettoopenthemasbinary,andeverythingworks,and
thenyouporttheprogramtoasystemwhere'\n'actuallyistranslated,andthenyouhavetofindallthosecasesandopen
thefilesasbinary.However,thisisnotthefaultofC++.Itisthefaultofthedistributednatureofthehumanrace,whichfails
tostandardizethesimplestthings.

Manyprogramsmayscrewupyourbinaryfilesduetothisfamilyofissues,forinstance,manyFTPclientswilldosounless
explicitlytoldotherwise.

[15.13]HowcanI"reopen"std::cinandstd::coutinbinarymode?
FAQ:There'snoportablewaytodoit.

FQA:That'sprobablythefaultofallthosedifferentincompatiblesystemsratherthanC++oranyotherprogramming
language.

[15.14]HowcanIwrite/readobjectsofmyclassto/fromadatafile?
FAQ:Readthesectionaboutserialization.

FQA:TheFQAdoesn'thaveasectionaboutaserialization.Shortsummary:you'reinforarudeawakening.There'sno
standardserializationmechanisminC++.Furthermore,there'snowaytodefineareasonablecustomonesincethere'sno
reflection(nowaytofigureoutthestructureofanarbitraryobjectgivenapointertoit,nowaytocreateanobjectofaclass
givenitsnameorsomeothersortofID,etc.).

However,therearemanycustompackagesforserialization(typicallythousandsofsourcecodelines,requiringyoutouse
hairymacros/templatesforeachserializedclassmember).Oryoucanrollyourown,oryoucandumpthewholesnapshotof
yourprocesstoafileinnonportableways(maybethecheapestthingtodomorefrequentlythanitsounds).

[15.15]HowcanIsendobjectsofmyclasstoanothercomputer(e.g.,viaa
socket,TCP/IP,FTP,email,awirelesslink,etc.)?
FAQ:Readthesectionaboutserialization.

FQA:Keepyourexpectationslow.

[15.16]Whycan'tIopenafileinadifferentdirectorysuchas"..\test.dat"?
FAQ:Because\texpandstothetabcharacter.Use\\ttosay"backslashfollowedbyt".

FQA:Youhavetoescapecertainthingssomehow,sothisisperfectlylegitimateunlikethefactthattheC++standard
libraryhasnowaytoopenadirectory,forexample.

http://yosefk.com/c++fqa/fqa.html 50/112
2/26/2015 C++ Frequently Questioned Answers

[15.17]HowcanItell{ifakey,whichkey}waspressedbeforetheuser
pressestheENTERkey?
FAQ:TheC++standarddoesn'tevenassumeyoursystemhasakeyboard.Sothere'snoportableway.

FQA:GoodfortheC++standard,butisthereareasonnottoprovideastandardinterfaceforsystemswhichdohavea
keyboard?

[15.18]HowcanImakeitsokeyspressedbyusersarenotechoedonthe
screen?
FAQ:Youcan't.Seeabove.

FQA:Yep,somesystemsdon'thavescreenswesureshouldn'tsupporttheonesthatdo.

Interestingly,theC++standardassumesthatyoursystemhaspersistentfiles,andhasseparateoutputanderrorstreams.
Evenmoreinterestingly,itassumesthatyoumightneedUnicodeoutputandlocales.You'dbesurprisedtofindoutsomeof
thestrangeplaceswheredevicescarryingdeadcodesupportingthesefeatureslive.

[15.19]HowcanImovethecursoraroundonthescreen?
FAQ:Usingwhicheverwaythatworksonyoursystem.It'snotrelatedtotheC++standard.

FQA:Youshouldhavespottedatrendbynow.

[15.20]HowcanIclearthescreen?Istheresomethinglikeclrscr()?
FAQ:Thereis,butnotintheC++standard.It'ssystemspecific.

FQA:Soarewindows,socketsandregularexpressions.Yousee,theC++standarddoesn'tassumeyouhaveascreen,a
networkcontrollerorhardwareforregularexpressionmatching.

ThelamestandardlibraryisanotheroneofthosethingsmakingusingC++ajoy.

[15.21]HowcanIchangethecolorsonthescreen?
FAQ:Dependsonyoursystem.TheC++standarddoesn'trefertothis.

FQA:Butthere'sanANSIstandardthatdoes.Therearesomeuglycharactersequencesyoucansendtocout/stdoutyou
don'tneedtocallanyspecialfunctions.Manyterminalssupportthis.

Freestoremanagement
Thispageisaboutoneofthemosthard,boringanddangerousthingsC++forcesyoutodomanuallykillingyourobjectsat
therighttime.Onedirtyjob,that.

[16.1]Doesdelete pdeletethepointerp,orthepointedtodata*p?
[16.2]Isitsafetodeletethesamepointertwice?
[16.3]CanIfree()pointersallocatedwithnew?CanIdeletepointersallocatedwithmalloc()?
[16.4]WhyshouldIusenewinsteadoftrustworthyoldmalloc()?
[16.5]CanIuserealloc()onpointersallocatedvianew?
[16.6]DoIneedtocheckforNULLafterp = new Fred()?
[16.7]HowcanIconvincemy(older)compilertoautomaticallychecknewtoseeifitreturnsNULL?
[16.8]DoIneedtocheckforNULLbeforedelete p?
[16.9]WhatarethetwostepsthathappenwhenIsaydelete p?
[16.10]Inp = new Fred(),doestheFredmemory"leak"iftheFredconstructorthrowsanexception?
[16.11]HowdoIallocate/unallocateanarrayofthings?
[16.12]WhatifIforgetthe[]whendeletingarrayallocatedvianew T[n]?
[16.13]CanIdropthe[]whendeletingarrayofsomebuiltintype(char,int,etc)?
[16.14]Afterp = new Fred[n],howdoesthecompilerknowtherearenobjectstobedestructedduringdelete[] p?
http://yosefk.com/c++fqa/fqa.html 51/112
2/26/2015 C++ Frequently Questioned Answers
[16.15]Isitlegal(andmoral)foramemberfunctiontosaydelete this?
[16.16]HowdoIallocatemultidimensionalarraysusingnew?
[16.17]ButthepreviousFAQ'scodeisSOOOOtrickyanderrorprone!Isn'tthereasimplerway?
[16.18]ButtheaboveMatrixclassisspecifictoFred!Isn'tthereawaytomakeitgeneric?
[16.19]What'sanotherwaytobuildaMatrixtemplate?
[16.20]DoesC++havearrayswhoselengthcanbespecifiedatruntime?
[16.21]HowcanIforceobjectsofmyclasstoalwaysbecreatedvianewratherthanaslocalsorglobal/staticobjects?
[16.22]HowdoIdosimplereferencecounting?
[16.23]HowdoIprovidereferencecountingwithcopyonwritesemantics?
[16.24]HowdoIprovidereferencecountingwithcopyonwritesemanticsforahierarchyofclasses?
[16.25]Canyouabsolutelypreventpeoplefromsubvertingthereferencecountingmechanism,andifso,shouldyou?
[16.26]CanIuseagarbagecollectorinC++?
[16.27]WhatarethetwokindsofgarbagecollectorsforC++?
[16.28]WherecanIgetmoreinfoongarbagecollectorsforC++?

[16.1]Doesdelete pdeletethepointerp,orthepointedtodata*p?
FAQ:Thatwouldbe*p.Thekeywordshouldhavebeendelete_whatever_is_pointed_by.Similarly,freeshouldhavebeen
calledfree_whatever_is_pointed_by.

FQA:Itreallyshouldhavebeen"".That'sright,thekeywordshouldhavebeenanemptystring.Youdon'tneedit.The
objectshouldliveaslongassomeonecanuseit,andwhenitbecomesunaccessibleandcannolongerbeusedbyanyone,
itshoulddie.Whyismakingsurethatthisiswhatactuallyhappensyourjob?

Ofcoursegarbagecollectionmaybetimeconsumingintheaverageand/orworstcase.Areyousureyourimplementationof
newisbetterinthisrespectthough?Atleastwithgarbagecollectionandmanagedpointersyoucandoheapcompaction.
Withnew/deleteandbarepointers,piecesofmemorybetweenusedblockstoosmalltosatisfyanactualallocationrequest
willaccumulate,andyou'lleffectivelyrunoutofmemory.Thisnicesituationiscalledexternalmemoryfragmentation.Tryit
withyourproductioncodethat'ssupposedtohavelong(nottomention"unlimited")uptimeit'sfun!

Andwhatifyoumakeamistake,onesinglemistakewithallthesedeletions?Eitheryou'llrunoutofmemory,oryour
programwillcrash,oritwillcorruptitsowndata.WhichiswhymanyexperiencedC++programmersdoeverythingtoavoid
explicitcallstonew.Instead,theyuseRAIIhavesomeconstructordothenewandthedestructordothedelete.Which
eventuallyleadstolotsofunnecessarycopyingyoucan'tpointtosomedatainsideadatastructuresincethedatastructure
maybeabouttodie,anditwillkillallitsdatawhetherornotsomeonepointstoit.Soyouhavetomakeacopyofthatdata,
andkeepbelievingthatmanualmemorymanagementiswhatmakesyourC++programssofast.

Ifmanagingthelifeanddeathofobjectsissuchabigdeal,perhapsthelanguageisn'tveryobjectorientedafterall,isit?

[16.2]Isitsafetodeletethesamepointertwice?
FAQ:Itisn't.Don'tdothat.Yourprogrammaycrashorcorruptitsowndata.Ifitworksinatest,itdoesn'tmeanitalways
works.Don'tdothat.

FQA:Whenyoudeletethepointer,itstillpointstothesameplacetheonlydifferenceisthattheplacewasmarkedas
"free"insomesystemspecificway.Thesecondcalltodeletewillprobablytrytomarkitas"free"again.Whichmaybe
problematicwhenit'snolongerfree,actually,becausesomeonehasalreadyallocatedanobjectthere,andyou'vejust
wipeditoutwithyourseconddeletecall,sonowstillothersomeonecanallocateanobjectthereandoverwritetheobject
you'vedestroyedsoimmorally.

Thereareotherwaysforthistofailsay,thecodemarkingblocksas"free"andassumingtheyaretakenmaycounton
somememoryrightbeforetheplacepointedbytheblockstartpointertocontainsomemetadataitnolongercontains,etc.

Here'swhathappensinmanagedenvironments.First,youdon'tdeleteanything:theenvironmentdoes.Second,itnever
deletesanythingunlessnobodypointstoit.Soyouareneverstuckwithpointerspointingtogravesofdeadobjects,which
mayalreadybeinhibitedbyfreshlycreatedobjects.Whichisgood,becausewhateveryourprojectis,memorymanagement
isnotoneofitsstatedgoals,isit?It'snicenottodosomethingyoudon'treallywanttodo.

[16.3]CanIfree()pointersallocatedwithnew?CanIdeletepointers
allocatedwithmalloc()?
FAQ:Youcan't.Don'tdothat.Yourprogrammaycrashorcorruptitsowndata.Ifitworksinatest,itdoesn'tmeanitalways
works.Don'tdothat.

http://yosefk.com/c++fqa/fqa.html 52/112
2/26/2015 C++ Frequently Questioned Answers
FQA:ThemanyduplicateC++facilities,suchasnewandmalloc,areugly,butusingmismatchingfunctionsforallocation
anddeallocationisnotlessugly.Whydoyouwanttodothat?It'slikeusinganopeningparenthesisandaclosingbracket.
Howcanyoucountonsomethinglikethistoworkreliably?

[16.4]WhyshouldIusenewinsteadoftrustworthyoldmalloc()?
FAQ:new/deletecalltheconstructor/destructornewistypesafe,mallocisnotnewcanbeoverriddenbyaclass.

FQA:ThevirtuesofnewmentionedbytheFAQarenotvirtues,becauseconstructors,destructors,andoperatoroverloading
aregarbage(seewhathappenswhenyouhavenogarbagecollection?),andthetypesafetyissueisreallytinyhere
(normallyyouhavetocastthevoid*returnedbymalloctotherightpointertypetoassignittoatypedpointervariable,which
maybeannoying,butfarfrom"unsafe").

Oh,andusingtrustworthyoldmallocmakesitpossibletousetheequallytrustworthy&oldrealloc.Toobadwedon'thave
ashinynewoperator reneworsomething.

Still,newisnotbadenoughtojustifyadeviationfromthecommonstyleusedthroughoutalanguage,evenwhenthe
languageisC++.Inparticular,classeswithnontrivialconstructorswillmisbehaveinfatalwaysifyousimplymallocthe
objects.Sowhynotusenewthroughoutthecode?Peoplerarelyoverloadoperator new,soitprobablywon'tgetinyourway
toomuch.Andiftheydooverloadnew,youcanalwaysaskthemtostop.

[16.5]CanIuserealloc()onpointersallocatedvianew?
FAQ:Guesswhatyoucan't.reallocmayendupcopyingmemory,andC++objectsdon'tliketohavetheirmemorycopied
withoutgettingnotified.Theyliketohavetheircopyconstructorsandoperator=handlethecopying.

Bytheway,whydoyouthinkmalloc/realloc/freeusethesameheapasnew/delete?

FQA:Thefactthatthere'snoreneworwhateveryou'dcallitisoneofthereasonstousecustomallocatorsinsteadofnew.
Youcanthenallocateuninitializedmemorywithmallocanduseplacementnewtocallconstructors.Codedoingthesethings
isusuallyasuglyassin,hardtogetrightandgetsinthewayofdebuggers.

ManyC++objectswilllivehappilyeverafterthey'removed(realloc'd).Adifferentsetofobjectsalwaysgetbrokenthose
pointingtotheoldplace.Theintersectionofthesesetsisnonemptysinceobjectscankeeppointersintothemselves.Which
isthespecialcasethat'ssortofsolvedbycopyconstructorsandoperator=(thesolutionissimplytohaveyouimplementthe
copyingsothatpointersaresetupcorrectly).

However,thegeneralcasecan'tbesolvedyoucan'tmoveaC++objectanddestroytheoldoneunlessyoucanprovethat
nopointersarelefttotheoldlocation.Thiscan'tbeprovedautomaticallyinthegeneralcase(thehaltingproblemandall
that).Whichiswhyyoucan'tdoautomaticheapcompaction,whichcouldsolvetheexternalfragmentationproblem.

Ifyourimplementationusestwoheaps,oneformallocandonefornew,thenitstinks,becausesometimesyouwantto
somehowreplacemallocwithsomethingelse,andit'snicetobeabletodoitonce(formalloc),nottwice(formallocand
new),andtwoheapsprobablymeanmorefragmentation,andwhat'sthepointoftwoheaps?I'veneverseenthisdone,butit
actuallyislegal.

[16.6]DoIneedtocheckforNULLafterp = new Fred()?


FAQ:No,thatwouldbebad.newthrowsanexception,soyoudon'thavetoinserttestsallovertheplace.Unlessyou're
usinganoldcompiler(youcanstillworkarounditandhaveanexceptionthrown).

FQA:C++exceptionsarefrequentlyworsethanhavingyourcodesimplyandstraightforwardlycrash(atleastinthelatter
case,youhaveagoodchancetofindthecallstackwherethathappened).Disablingexceptionsupportatyourlatest&
greatestcompilerissometimesagoodidea.

Ifyoureallyhavetowritecodehandlingoutofmemoryconditionsgracefully,that'snotaseasyataskassimplycatchinga
C++exception.First,you'llprobablyhavetoavoidrecursion(C++doesn'tthrowstackoverflowexceptions,youknow,sothe
programcan'tbehavegracefullywhenyou'reoutofthatmemory).Second,whatareyougoingtodowhenyou'reoutof
memory?Takeintoaccountthatyou'llneedmemorytodoityoumightneedtoreservesomeinadvance.

Andtherearen'tthatmanychoicesinmostcases.Youcanexitwithanerrormessageinsteadof"hard"crashing.Youcan
showamessagesayingthatthere'snotenoughmemoryandcouldtheuserpleaseclosesomeprogramsandthenyou'd
retry,ormaybetheuserwantsyourprogramtoquit?Allthesecanbedonewithoutexceptions.

http://yosefk.com/c++fqa/fqa.html 53/112
2/26/2015 C++ Frequently Questioned Answers
Exceptionscanbesortofhandywhenyourapproachisto"abortthecurrentoperation",butexceptionsarenotaverygood
waytodeveloprobustcode,andifyouactuallywanttodealgracefullywithoutofmemorysituations(youprobablynoticed
thatit'srarelydone),that'swayoutoftheirleague.Thereasonisthatwithexceptions,therearemanywaystomakesubtle
errorsinyourerrorhandlingcode,andwhensomeaspectofyourapplicationisimportant,you'reusuallybetteroffmaking
thehandlingofthataspectexplicitandclear.

[16.7]HowcanIconvincemy(older)compilertoautomaticallychecknewto
seeifitreturnsNULL?
FAQ:Youcanpassacallbackfunctionthrowinganexceptiontostd::set_new_handler.Thiswillwork,exceptforglobal
variablescallingnewbeforeyousetyourhandler.Thereisnowaytomakesureyourhandlerissetfirstevenifyousetitin
theconstructorofaglobalvariable,thatvariableisnotnecessarilythefirstonetobeconstructed.

FQA:Iwonderwhyyouwantnewtothrowexceptions.Thisdesiremaybetheindicationofacertainkindofmindset.Hmmm,
let'sconductatest:areyouhappywiththeFAQ'ssolution,orareyouactuallybotheredbythefactthataconstructorofa
globalvariablemayrunoutofmemorywithoutthrowinganexception?

Ifthisoptionscaresyou,itprobablymeansthatyouliketodohairythingsbeforemaininundefinedorder,includingthrowing
andcatchingexceptions,whichconfirmsmyworstfears.Ihopeyougetoutofthesehabitsbythetimewehappentowork
onthesameproject.

If,onthecontrary,youthinkthatglobalconstructorsshouldn'tgetthatcomplicated,yourapproachisapparentlyalittlebit
morepractical,andnowI'mreallypuzzled.Areyouabsolutelysureyouwantnewtothrowexceptions?

[16.8]DoIneedtocheckforNULLbeforedelete p?
FAQ:deletealreadydoesthat,sono,youshouldn't!Youcouldgetthetestwrong,andyou'llspendtimetestingboth
executionpathsasrequiredbytestingmethodologies.

FQA:ApparentlytheFAQiswrittenforimbecilesthatcan'ttestforNULL,andtheydon'ttestthecodeafterwritingittoseeif
itworked,buttheydomechanicallytestallbranchesbecauseoftestingmethodologies.Ifyouwanttoreallycreateavivid
imageofamemberoftheFAQ'stargetaudienceinyourimagination,thinkaboutthis:justhowdoestheidiotcoverboth
executionpaths?ThepoorcreaturemustartificallycreatecaseswherepisNULL,withouthavingtherestoftheprogram
crash.Whichcanbetrickyenoughtobeinconsistentwiththerestofourdataaboutthementalcapabilitiesofthis
programmer.Andnowwegetaclearpicture:theFAQisdesignedforextraterrestrialintelligencestrugglingwiththemany
difficultiesofC++.

Actually,thereisnoreasontobemeanthistime.Onceinalifetimethosepeopleactuallymadesomethingeasy.Maybe
theywereinspiredbytheexampleoffree,whichalsoacceptsnullpointers.Prettyinconsistentwiththespiritofthe
language.WhichiswhyIwasverysurprisedwhenIfirstfoundthisout.

[16.9]WhatarethetwostepsthathappenwhenIsaydelete p?
FAQ:WhenpisaT*,thefirststepisp->~T();,andthesecondisoperator delete(p);.

FQA:Uglysyntax,isn'tit?Especiallythefactthata+bisthesameasoperator+(a,b),butdelete pisnotatallthesameas
operator delete(p).

Thesemanticsareconsistentwiththedecouplingofallocation(operator new)andconstruction(T()).Thisdecoupling
breaksencapsulationwithoutadmittingit(thecallermustknowthesizeoftheobjectsoftheclassatcompiletime,which
meansitmustknowalltheprivatemembers)inordertoincreaseefficiencyinstraightforwardimplementations(whichcan't
dojustintimecompilationwithoptimizationandhavetoknowthesizeatcompiletimetooptimizeallocation).Whichiswhy
C++codeisrecompiledallthetime.

[16.10]Inp = new Fred(),doestheFredmemory"leak"iftheFredconstructor


throwsanexception?
FAQ:No,becausethecompilereffectivelygeneratesatry/catchblockaroundtheconstructorcall,andwhenexceptions
arethrown,thecatchpartdeallocatesthememoryandrethrowstheexception.

FQA:Ifyouthrowexceptionsinconstructors,makesuretheyarecaughtwhencustomallocatorsareused(thekindthat
lookslikethis:new (pool.alloc()) Fred()).

http://yosefk.com/c++fqa/fqa.html 54/112
2/26/2015 C++ Frequently Questioned Answers
Ifyoudon'tthrowexceptions,theimplicittry/catcharoundnewisoneillustrationofthefactthatexceptionsincreasethesize
ofyourcodeevenwhenyoudon'tusethem.Onegoodthingisthatmostcompilershaveaflagdisablingexceptions.

[16.11]HowdoIallocate/unallocateanarrayofthings?
FAQ:Youallocateitwithp = new T[N]anddeallocatewithdelete[] p.Usingdelete pisanerror.

FQA:YoucanonlydothatifThasadefaultconstructor(onethatcanworkwithoutarguments).Whichisonemorereason
toavoidnontrivialconstructors.Alternatively,ifyou'drathercreateaproblemthansolveone,youcanreplaceyourevil
arrayswithstd::vector.

[16.12]WhatifIforgetthe[]whendeletingarrayallocatedvianew T[n]?
FAQ:You'llinfectyourprogramwithanincurabledecease.Itwilldosomethinglikecorruptitsdataanddie.

FQA:Ifyouwanttorealizetheidiocyofthisruleinitsfullglory,considerthis.newcallsmallocorsomeotherallocator,andit
passesittheblocksize.Theallocatedpointeristhenpassedtodelete,butthesizeisnot.Howdoesdeleteknowtofreea
blockoftherightsizenottoolittle,nottoomuch?Ithastostorethesizesomewhere,doesn'tit?Butofcourseitcan'tbe
botheredtofigureoutthenumberofobjectspointedbythepointer(like,dividethestoredsizebysizeof(*p),makingan
actualuseof"typesafety")soitcancallthedestructorsproperly.

Butwait,there'smore!What'sthedealwithdatacorruption?Shouldn'ttheworstpossibleeffectbearesourceleakdueto
thefactthatsomedestructorsarenotcalled?

Here'sthebestpart.operator new[]allocatesalittlebitmorememorythanit'saskedforinordertostorethenumberofthe
friggingobjectsinthatplace(itcanalsobedoneinotherways,buttheeffectisequivalent).delete[]usesittocallthe
destructorsforalltheallocatedobjects.Sincenewdoesn'tstoreanynumberandonlyallocatestheamountofmemoryitwas
toldto,itbecomesclearwhymismatchingthenewanddeleteoperatorswillleadtodatacorruption.

Thebottomlineisthis:C++storesthenumberofobjectsinablockoncewhennewiscalledandtwicewhennew[]iscalled,
anditwillratherhaveyouintroducelethalbugsinyourprogramthanusetheinformationtohelpyougetitright.Nowthatis
whatIcall"hospitality".

[16.13]CanIdropthe[]whendeletingarrayofsomebuiltintype(char,int,
etc)?
FAQ:Noyoucan't.Youmaythinkthatyoucan,becauseinthasatrivialdestructor.Butit'snotjustaboutdestructors.For
example,whatifsomeonereplacesoperator new[]andoperator delete[]inawayincompatiblewithmismatching
new/delete[]calls?

FQA:Yeah,didyouthinkaboutthat?AndwhatifyouuseanarrayofInt,whichisatypedef,andsomeonechangesthe
typedeftoSmartIntClassinsteadofplainoldint?Thinkaboutit.That'swhatyourbrainisfor:thinkingaboutexciting,useful
thingslikethis.

Theseriousansweristhatifalanguagehastwosetsofsimilarmatchingoperators,thanaprogrammerisbetteroffavoiding
mismatchesbetweenthoseoperators.Thefactthattherereallyshouldhavebeenonedeleteoperator,no,wait,makeit
zero,maybeareasontoswitchtoadifferentlanguage,butnottoviolatetherulesofalanguage.

[16.14]Afterp = new Fred[n],howdoesthecompilerknowtherearenobjects


tobedestructedduringdelete[] p?
FAQ:Singalong:"It'sakindofmagic..."

Therearetwocommonwaysusedbyourfriendsthecompilerimplementingmagicians.Oneistoallocateextramemoryand
storethenumberofobjectsthere.Theotheroneistouseanassociativearraymappingfrompointerstosizes.

FQA:Youmaywonderwhytheseclevermagiciansdon'trelyonmalloctodothemagic,andhaveyouendupwiththeblock
sizestoredtwice:youasknewfor8bytes,thennewasksmallocfor12bytes,thenmallocaskssbrkorwhatever'sdownits
gutsfor16bytes.

Theanswerisofcoursemodularity.Translation:whyshouldtheimplementoroftheC++languagebothertofigureoutthe
detailsofmallocwhenthere'stheeasieroptionleaveittotheimplementoroftheClanguageandsimplyandportably

http://yosefk.com/c++fqa/fqa.html 55/112
2/26/2015 C++ Frequently Questioned Answers
implementnew[]ontopoftheCruntime?4bytesofyourmemoryaresurelynotagoodenoughreason.

"Magic".Thenextthingyouknow,they'llcallexploitingsecurityholesinyourOStoutilizesomeofthoseunusedprocessor
&memoryresources"magic".

[16.15]Isitlegal(andmoral)foramemberfunctiontosaydelete this?
FAQ:Youcandothis,aslongasyouaresuretheobjectisallocatedwithnew,andthepointerisnotusedforanythingatall
afterdelete this.

FQA:Thisisabitweird,anditprobablycausesmanypeopletogetalarmedandstartanxiouslylookingforplacesthatmight
touchthedeletedobject(asifitweremorelikelythanalessexoticaccesstoadanglingreference).Anditforcestheuserof
aclasstoallocatetheobjectswithnew,whichisagainstthe(misguided)spiritofC++andthereforeanothersourceof
confusion.Atleastprovideastaticmethodthatallocatesobjectswithnewanddeclarethedestructorsprivatetodocument
yourintenttocontroltheallocation.

Whydoyouwanttodoitanyway?Ifyouwanttoimpresspeople,whynotdosomerealmagicactualfunctionality,notjust
yetanothersyntacticexercise?

[16.16]HowdoIallocatemultidimensionalarraysusingnew?
FAQ:Theanswerisverylongwith3largecodelistings.

FQA:Thereisnooperator new[][]inC++itdecidedthatnewandnew[]aresufficientithadmanystupidreasonsto
decidethatway.Anyway,youhavetwooptions:allocateaflatarrayandmanagetheNdimensionalindexingmanually
(generatingonedimensionalindexesusingexpressionslikex+y*width),oryoucanallocateanarrayofarrays(correction).
For2dimensions,youneedtoallocateanew T*[M]andtheninaloopwithMiterationsallocateanew T[N].

Withthesecondwayyougetmorenaturallookingindexing,butworseperformance(lessspeed,morespace).Itmaybe
convenientifyouneedeachonedimensionalarrayinthetwoormoredimensionalarraytohaveadifferentlength,buteven
thenit'sprobablybettertofakeitwithaflatterkindofarrayinuglywaysifyoucareaboutperformance(bytheway,ifyou
don't,makethebestofittryasafelanguage).

[16.17]ButthepreviousFAQ'scodeisSOOOOtrickyanderrorprone!Isn't
thereasimplerway?
FAQ:Sureitis!YoucandefineaMatrixclassandhaveitdoallthedirtywork.Whichisgood,asshouldbeobviousto
anyonefamiliarwithStarTrek2(areferencefollows).

FQA:Ididn'tseeStarTrek,butmovingthedirtyworktoasingleplacedoesn'tmakethatwork"simple".Ofcourseit'sbetter
thandoingthatworkoverandoveragain,buthowmanymultidimensionalarrayclasseshaveyouseen,andwhathappens
whensomeonetriestoconvertbetweenthem?Imeanitcan'tbea"singleplace"unlessthatplaceisthecompiler.

Bytheway,ifyouneedperformance,youcan'treallyencapsulatethelayoutofthemultidimensionalarray,becauseyou'll
needtodothingslikegetonecolumntotheright(withflat_index+1)oronerowup(withflat_index+row_width),insteadof
computingthingslikex+(y+1)*row_widtheverytimethroughtheinnermostloop.

Youcantrytodefineallkindsoffunctionslikeincrement_by_row.Ifyoureallybelievethatitwillmakeitpossibleto
"transparently"changetherepresentationlater(thusturningalltheoptimizationscarefullydevelopedforthisrepresentation
intopessimizations),goaheadanddefineandoptimizehordesofsuchtinyfunctionsandkeeplyingtoyourselfabouthow
thismakesyourcodemorereadable.

Datarepresentationisveryimportant.Toobadsomanypeoplebelievethattheonlyimportantthingaboutdataistohideit
behindcode(interfaces)sothatyoucan"alwayschangethedatarepresentationlater".Whilethismayberightinthe
majorityofcases,itislikelytobewronginthemostimportantcases.

[16.18]ButtheaboveMatrixclassisspecifictoFred!Isn'tthereawayto
makeitgeneric?
FAQ:Ofcourse!Youcanusetemplates!

FQA:Thisway,notonlywillyourcoderunslowlyitwillalsocompileslowly.

http://yosefk.com/c++fqa/fqa.html 56/112
2/26/2015 C++ Frequently Questioned Answers

[16.19]What'sanotherwaytobuildaMatrixtemplate?
FAQ:Youcanusestd::vectorinsteadofbarepointers!

FQA:Youcanalsouseanyofthenumerousarrayclassesimplementedbeforestd::vectorwasintroducedintotheC++
standardlibrary(whichwaslongafterC++becamewidelyused).

Alternatively,youcanalsouseanyofthenumerousmatrixclassesimplementedbeforestd::matrixwasintroducedintothe
C++standardlibrary...Actually,makethat"beforestd::matrixwillbeintroducedintotheC++standardlibrary".Canyou
explainwhytheC++standardincludesstd::vectoraclassquitesimilartobuiltinarrays,butdifferentbutdoesnot
includestd::matrix,aclassthatwouldbequitesimilartobuiltin2Darrays,butdifferent?Here'samoredifficultquestion:is
itgoodorbadthatwedon'thavestd::matrix,providedthatwedohavelessthanoptimalbuiltin2Darrays?Beforeyou
answer,considertypeconversions,dynamicresizing,literalvalues,tellingthesizeofanarrayatruntime...

That'swhatC++isallabout:thedevelopmentofyourethicaljudgment.Everybodycantellgoodfrombadchoosing
betweentheuglyandthedisgustingtakesrealwisdom.

[16.20]DoesC++havearrayswhoselengthcanbespecifiedatruntime?
FAQ:Thatwouldbeyesthere'sstd::vector.

Actually,it'sanoyoucan'tdoitwithbuiltinarrays.

Waitaminuteyoucandoitwiththefirstindexofabuiltinarray,forexample:new T[run_time_val][compile_time_val].

Youknowwhat?Arraysareevil.

FQA:std::vectorisnotanarray,it'saclassthatlookslikeanarrayuntilyoutrytoinitializeitwith{1,2,3}orpassanarray
toafunctionexpectingavectororgetahugecompilererrormessage.Builtinarraysdon'tbehavelikethis.

C++inheritsthefollowingruleabouttypesfromC:thesizeofatypeisalwaysknownatcompiletime,andyoucangetitwith
sizeof.ThisruleisusefulinCbecause,togetherwithotherruleswhichareviolatedinC++,itmakesitquiteeasyto
mentallymapsourcecodetoassemblycode(sortof)andestimateruntimeperformance.InC++it'snolongeruseful,
becausetellingthemeaningofC++codeisnearlyimpossible,nottomentionreasoningaboutitsperformance.

Anyway,thelengthofabuiltinarrayispartofitstype,soifitcouldbedynamic,itwouldviolatetheexusefulrule.Soit
can't.However,builtinpointerscanpointtoanarrayoflengthdefinedatruntime.SoyoucanhaveaT* ppointingto
run_time_valobjects,butyoucan'thaveanarrayoftypeT[run_time_val].Whichmeansthatyoucan'tallocatesucharrays
onthestack(unlessthecompilerdecidestoalmostviolatetheexusefulruleandsupportit,thewayGNUC/C++does,for
example).

ThebuiltinC++arraysareinheritedfromCwithoutchanges(well,exceptforconstructor/destructorcallsandnewinaddition
tomallocandotherstuffofthiskind),soifyoucareaboutdetails,thebestplacetolookismaterialaboutC.Thisisoneof
themanyexamplesillustratingthatyouhavetoknowCinordertoreallyunderstandC++.

[16.21]HowcanIforceobjectsofmyclasstoalwaysbecreatedvianew
ratherthanaslocalsorglobal/staticobjects?
FAQ:Youcandefinetheconstructorsprivateandprovidepublicfunctionswhichreturnpointerstoobjectsallocatedwith
new.Whichgoesbythefancynameof"TheNamedConstructorIdiom".

FQA:Whydoyouwanttoforcethis?Allocatinglocalsismoreefficientthannew,andyouwouldn'thavetoworryabout
delete,either.Thecostisthatwhenyouchangetheprivatemembersoftheclass,allcodeusingitgetsrecompiled.

Wait,isthatwhatyouwanttoavoidrecompilation?Inthatcase,the"NamedConstructorIdiom"defeatsthepurpose
changeaprivatememberandyoustilltriggerarebuild.YoucaneitherdropC++classesandstorethestateinaCstruct
(placeaforwarddeclarationintheheaderfileandthefulldefinitionintheimplementationfile),oryoucanwrapthisexact
solutionwiththecodeofanextraC++classjustbecauseCisevil.Thelatterwayisknownas"ThePimplIdiom"("pimpl"
apparentlystandsfor"pointertoimplementation").

Idiomsmaketheworldmove.EspeciallytheDesignPatternIdiom.OrtheIdiomDesignPattern.Orsomething.

[16.22]HowdoIdosimplereferencecounting?
http://yosefk.com/c++fqa/fqa.html 57/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:Twolargecodelistingsaregiven(aquotefromtheselistings:// DO NOT CHANGE THE ORDER OF THESE STATEMENTS!),
followedbyaboldclaimthatnowyouhaveawaytodosimplereferencecounting.

FQA:Youdosimplereferencecountingbyusingalanguagewhichdoesreferencecounting(orgarbagecollectionyou
probablydon'tcareifyouwantit"simple").

YoudocomplicatedandbrokenreferencecountingbyusingC++,creatingsmartpointerclasses(andsmartarrayclasses,
andsmartmultidimensionalarrayclasses),wrappingyourprivateconstructorswithpublicfunctionsreturningsmartpointers
toobjects(orsmartarraysofobjects)tomakesureallobjectsareactuallypointedbysmartpointerssothereference
countingisnotentirelyworthless.

Congratulations!You'vejustwastedlotsandlotsoftimetoemulategarbagecollectionontopofC++.Well,thecodedoesn't
compileasfastasitwouldwithbuiltingarbagecollection(allthosesmartpointertemplates),andtheerrormessagesarea
bitcryptic(allthosesmartpointertemplates),andtherearethosetrickycaseslikecyclicreferencesyoustillfailtodealwith
(despiteallthosesmartpointertemplates),andforeveryclassyouwriteextracodewrappingconstructors,andthewhole
thingdoesn'tplaywellwithexistinglibraries(whichusedifferentsmartpointertemplates),and...

WhydoyouwanttodoreferencecountinginC++?

[16.23]HowdoIprovidereferencecountingwithcopyonwritesemantics?
FAQ:Youcanhaveyourclasskeepallthedatainastructurepointedbyamemberpointer_data,andtheneachmethod
thatwantstomodifytheobjecthastocheckthereferencecount,andifthedataissharedbyseveralobjects,thedatamust
beclonedbeforethemodification.

FQA:Ultimately,whatareyoutryingtoachieve?Ifyoucarealotaboutefficiencyandyoucarealotabouthighlevelof
abstractioninthesamepieceofcode,there'sprobablynoeasysolutionforyou.Areyousureit'sthesamecode?Ormaybe
youwantefficiencyinsomeplaces,andhighlevelofabstractioninotherplaces?Thenyoucanusetwodifferentlanguages.

Ifit'sreallythesamecode,thebestsolutionisprobablytowriteyourownlittlelanguage.It'snotashardasitsounds,and
notsostrangethinkaboutit:apparentlyyoumustwritealotofcode(iftherewasn'talotofit,itwouldn'tbeaproblem)in
someprettyspecificdomain,becausethere'snohighlevellanguagewhichsupportstherightbuiltinfacilities.Oristhere?
Areyoulookingforcopyonwritestringsorsomething?StringprocessinginC++?Doyourselfafavorandstoprightthere.
Usealanguagewithdecentbuiltinstrings.

Iftherereallyisnogoodexistinghighlevellanguageforyourjob,basicallywhatyouhavetodoismetaprogramming:you
wantsomethingwhichisnotdirectlyrelatedtothespecificmeaningofyourprogramyouwantobjectsofprettymuch
arbitraryclassestobehaveinacertainway.Whichmeansyouwantanewlanguage.Youcandoitwithyourowncompiler
oryoucandoitinasystemwhichsupportsmetaprogrammingwell(thetwoapproachesarereallyprettyclose).C++meta
programmingisanightmarethefacilitiesforitareverypoor,andthere'slotsofstrangefeaturesalreadyinthelanguage
thatyoumustinteroperatewith.Youhavebeenwarned:thispathleadstothegatesofmadness.

Clarification:I'mnotsayingthatmetaprogrammingislikelytobethesolutionwhenyouwantcopyonwrite.Onaverage,
thatwouldprobablybeoverengineering.However,inthecaseswhereitindeedisoverengineering,soistheFAQ's
solutionthewaytogoisprobablytohavetheusercodeexplicitlycopyobjectsuponmodifications.Andwhenthere's
enoughcodeinvolvedtomakethattedious,thentheC++solutionalsogetstedious,andthat'swhenmetaprogramming
couldbeappropriate.

[16.24]HowdoIprovidereferencecountingwithcopyonwritesemanticsfor
ahierarchyofclasses?
FAQ:Youdoitbywritingalotofcode!Likethis:
code;
code;
code;
lots of code;
more code;
two screens of code;
//boy is this FUN!
code;

FQA:Here'sasolutionforanotherhierarchyofclasses(youmighthavemorethanoneinyourprojectithappens,andthe
FAQs"solution"isdoneonapermethodbasis,andthereisn'tevenawaytoiterateoverthemethodsofaclassinC++,not
tomention"transparentlyinstrumentthemethodsofaclasswithcustomlogiclikecopyonwrite"):
code;

http://yosefk.com/c++fqa/fqa.html 58/112
2/26/2015 C++ Frequently Questioned Answers
code;
//why am I doing this?
code;
code;
//help
code;
//I think I'd rather become a farmer

Seriously,I'mnotgoingtodiscussthenightmarethatistheFAQ'sproposedsolution.FollowthelinktotheFAQ'sanswerif
youwanttocheckitout.WhatIwouldliketopointoutisthatit'spossibletodoallthistransparentlyifyourenvironmenthas
goodsupportformetaprogramming.Forexample,somelanguagesletyouwriteyourowncodetoimplementobject
attributemodification(thesimpleroption),and/orautomaticallygeneratewrapperclassestointerceptmethodschanging
objects(themorecomplicatedoption).Eitherway,youendupwithO(1)codetosolvetheprobleminsteadofO(N),whereN
isthenumberofclassesinvolved.

[16.25]Canyouabsolutelypreventpeoplefromsubvertingthereference
countingmechanism,andifso,shouldyou?
FAQ:Youcan't,andyouusuallyshouldn't.(Yes,that'sprettymuchwhattheFAQsays:sometimesyoushoulddowhatyou
can't.Justwhatdoes"should"meaninitswarpeduniverse?)

Therearetwoholesinthearmor.First,yourSmartPtrprobablyhasanoperator*thatreturnsabarereferencetoanobject.
SoyoucanendupwithDumb* p = &*smart_p;.Thiscanbesortofclosedusingseveralapproaches,eachworsethanthe
othersinitsownuniqueway.Andthentherearewaystogetthebarepointerwithsyntaxlikesmart_p.operator->(),
returningaDumb*.

ThesecondholeisthatsomeonecanhavedanglingreferencestoSmartPtr.Thiscan'tbepreventedevenbyreturninga
SmartPtrPtrinanoverloadedoperator&,becauseC++hasreferences(rememberthenewfeatureyoushoulduseinstead
oftheevilpointers),andthere'snothingyoucanoverloadtopreventsomeonefromtakingareferencetoyourSmartPtr.

Usecodereviewstofigureoutwhat'sactuallygoingonwithallthosesmartpointers.

FQA:Youcan'tfakewhatyoudon'thave(IthinkthequoteisattributedtoS.Cray).C++doesn'thavesafememory
management.Fakingsafememorymanagementleadstostillunsafememorymanagement,withtheimportantbonusof
obfuscation.

Youcanabsolutelypreventpeoplefromsubvertingthereferencecountingmechanismbyusingaprogramminglanguage
thatabsolutelypreventspeoplefromsubvertingitsbuiltinmemorymanagementmechanisms.

[16.26]CanIuseagarbagecollectorinC++?
FAQ:Sureyoucan.Let'scompareittosmartpointertechniques.Garbagecollectionisnotasportable,buttypicallymore
efficient,anditcanhandlecyclicreferences,anditworksbetterwithothers'librariesbecauseyoudon'tneedtoexplicitly
changethepointersfromdumbtosmartoranythinglikeit.However,sometimesobjectscanleakaC++garbagecollector
can'ttellapointerfromarandombitsequencethatjusthappenstolooklikeapointer.

FQA:Assumingyouliveinafreecountry,what'stheretostopyoufromusingagarbagecollectorinC++?Sure,thereare
minorobstacles,forexample,itdoesn'treallywork,butit'sstillafreecountry,isn'tit?

Supposeyoucanusegarbagecollection,whichmeansthatyouarenotworriedaboutinterferencewithrealtime
requirements.WhyareyouusingC++?Whynotuseasafelanguageinstead?LooktheC++FAQadmitsthatgarbage
collectionismoreefficientthanC++"smartpointers"allovertheplace,andmorecorrect(cyclicreferences),andthesingle
correctnessproblemitmentions(randombitpatterns)vanishesinamanagedenvironment.Sowhat'stheproblem?

IfyouthinkyouneedtouseC++,dealwiththefactthatitdoesn'thavegarbagecollection,andyoumustmanagememory
manually.Oryoucandealwiththeotherfacts.Forexample,whathappensiftwolibrariesrelyingondifferentgarbage
collectorsaresupposedtoworkinthesameprogram?Whathappensifcodeincompatiblewithgarbagecollection(because
itdoes"clever"thingswithpointers,likeone_based_array = (int*)malloc(arr_size)-1)?Whataboutdestructors?C++
garbagecollectorsdon'tknowwhatthey'refreeing,soyoucan'thavefinalizationfunctions.Whataboutallthosehappy
customallocatorsC++programmersadoresomuch?Whatifamallocedobjectpointstoanobjectallocatedfromsucha
custompool?Thedestructoroftheouterobjectwiththepointerisnotgoingtobecalledsowhoisgoingtodeallocatethe
pointedobjectfromthepool?

C++doesnotfeelpain.Itcan'tbereasonedwith.Startingafightisabigmistake.IfyouwanttouseC++,youmustlearnto
loveitthewayitis,inparticular,manageyourmemorymanually.

http://yosefk.com/c++fqa/fqa.html 59/112
2/26/2015 C++ Frequently Questioned Answers

[16.27]WhatarethetwokindsofgarbagecollectorsforC++?
FAQ:Thereareconservativeandhybridgarbagecollectors.Theconservativeonesjustlookforbitsequenceslookinglike
pointers.Thehybridonesrequiretheprogrammertospecifysomelayoutinformationexplicitlyinthecode(buttheystill
traversethecallstackconservativelywhentheylookforpointers).

Garbagecollectorsmaycausememoryleakswhenabitpatternlookinglikeapointerismisinterpretedasaproofthatthe
blockpointedbythis"pointer"isstillinuse.Andsomeillegalprogramsmay"confuse"garbagecollectors(that'stheword
usedbytheFAQ)bykeepingpointersoutsideofallocatedblocks.Whycan'ttheseprogrammersbehavereasonably?

FQA:Let'sstartwithadifferentquestion:what'stheproblemwithgarbagecollectioninC++?Answer:thereisnowayto
inspectthestateofaC++programandtellwhichblocksareinuse.Inenvironmentsdesignedtosupportgarbagecollection,
youcandothatbycheckingiftheprogramcanreachtheblockusingoneofthepointersitcurrentlykeepsinitsmemory.
ButinC++,youcan't.First,youdon'tknowwheretheprogramkeepspointers(norealruntimetypeinformation),and
second,pointersthatdon'tpointintoablockcanbeusedtocomputepointersthatdopointintothatblock(unsafepointer
arithmetics).

Soalongcomethememoryleaks,andthe"confusion".Andwhathappenswhenagarbagecollectionis"confused"?I'lltell
youwhathappensitfreesanobjectwhichisstillinuse.Theresultisacrashoradatacorruption.Doyouthink"confused"
isalegitimateeuphemisminthiscontext?"Oh,I'msoconfused!IthinkI'llkillyourprogramnow."

Astothe"unreasonable"programmerswell,adjustingapointertopointbeforeanallocatedblockisoneefficientwayto
implementonebased(insteadofzerobased)arrays,amongotherthings.Ofcourseyoucanallocateanextraelementand
avoidviolatingtherules.Butmostpeopledon'tknowtheserules,becausealthoughtheyareapartofthelanguage
definition,theyarenotenforcedinthewidespreadimplementations,anddon'tbecomeapartofthementalmodeldeveloped
byprogrammersastheygainfamiliaritywiththelanguage.

Thatis,notonlydoesitworkwhenoneimplementsonebasedarraysthiswayonedoesn'tseeareasonforitnottowork:
experienceconsistentlytellspeoplethatC++pointersarejustakindofinteger.Formally,therearereasonsforthistobe
illegal(like,duh,whathappensifyouwantgarbagecollection?)butmostpeoplearenotlanguagelawyers.Inpractice,
whatmattersisthedefactostandard(that'swhyit'scalled"defacto").

[16.28]WherecanIgetmoreinfoongarbagecollectorsforC++?
FAQ:Here.

FQA:Don'tbother.IfgarbagecollectionworkedinC++,youwouldhearaboutit.C++hasbeenaroundfordecades,there
arehundredsofthousandsofC++programmers,andmegatonsofC++codewithzillionsofmemorymanagementbugs.If
someoneimplementedaworkingsolutionforthisproblem,they'dbecomerich,famous,orboth,andthegarbagecollector(s)
wouldbeeverywhere.

Whydoyouthinkyoudon'tseetoomanyaround?

Exceptionsanderrorhandling
ThispageisaboutC++exceptionsanerrorhandlingfacilitywhichmaybeworsethandereferencinganullpointerupon
error.

[17.1]Whataresomewaystry / catch / throwcanimprovesoftwarequality?


[17.2]HowcanIhandleaconstructorthatfails?
[17.3]HowcanIhandleadestructorthatfails?
[17.4]HowshouldIhandleresourcesifmyconstructorsmaythrowexceptions?
[17.5]HowdoIchangethestringlengthofanarrayofchartopreventmemoryleaksevenif/whensomeonethrowsan
exception?
[17.6]WhatshouldIthrow?
[17.7]Whatdoesthrow;(withoutanexceptionobjectafterthethrowkeyword)mean?WherewouldIuseit?
[17.8]HowdoIthrowpolymorphically?
[17.9]WhenIthrowthisobject,howmanytimeswillitbecopied?
[17.10]ExceptionhandlingseemstomakemylifemoredifficultclearlyI'mnottheproblem,amI??
[17.11]IhavetoomanytryblockswhatcanIdoaboutit?

[17.1]Whataresomewaystry / catch / throwcanimprovesoftware


http://yosefk.com/c++fqa/fqa.html 60/112
2/26/2015 C++ Frequently Questioned Answers

quality?
FAQ:You'llhavelessifstatementsinyourcode:youwon'thavetocheckforerrorseachtimeyoucallafunction.
Conditionalstatementsareknowntocontainmorebugsthanotherstatements.Withlessiftests,you'llshipabetter
product,faster.

FQA:Thisiscargocultprogramming.Conditionalstatementsareerrorpronebecausetheyareusedtohandlecomplicated
scenarios,whereanactioncanresultinmanydifferentoutcomes,whichaffectthenextactions.Inordertomakeerrorsless
probable,onehastosimplifythemodelofthedesiredbehaviorofthesoftware.Theproblemisthecomplexitythatleadsto
ifstatements,nottheifkeyword,andusingdifferentkeywordsisnotgoingtosolvetheproblembyitself.

Exceptionsaresupposedtosimplifytheerrorhandlingmodelbasedontheassumptionthatinmostcases,afunctionthat
detectedanerrorcan'thandleit,andhastopropagateittothecaller.Finally,a"highlevel"enoughcallerisreachedand
actuallymakesadecision(popsupanerrormessage,triesadifferentaction,etc.).

Despiteitspromises,thisapproachhasinherentproblems.There'sa"social"problemwithexceptions,peoplearenot
awareofthedifferenterrorsthatmayhappeninthecodebecausemostofthecodedoesn'tdealwitherrors.Andwhen
peoplerarelythinkaboutaparticularaspectofanapplication,ultimatelythisaspectisunlikelytobehandledwell.There'sa
more"technical"problemfunctionsessentiallydoingnothinguponerrorexceptforpropagatingerrorstothecallerstillcan't
becompletelyunawareoferrors.That'sbecausetheymayneedtoreleasetheresourcestheyacquiredbeforereturningto
thecaller,whichmayleadtomoreerrors,whichmustalsobehandled.Finally,inpracticeexceptionsupporthasruntime
overhead,andverysignificantcodesizeoverhead,evenifexceptionsareneverraisedatruntime,andeveniftheyarenot
mentionedinyourcode.C++devoteesmayclaimotherwiseyoucancheckbycompilingyourcodewithandwithout
exceptionsupport(ifyourcompilerdoesn'thavesuchaflag,compilecodeasCandasC++instead).Thisisunacceptable
inresourceconstrainedsystems.

Still,inmanycases,thebenefitsofexceptionsaremoreimportantthantheirproblems.Forexample,ifyourlanguage
managesmemoryautomatically,theproblemofreleasingacquiredresourcesbecomesasmallone(youonlyhavetocare
aboutfiles,etc.,whichareatinypartofthe"resources"usedbyaprogrammostofthe"resources"arememory).Ifyour
languagethrowsexceptionswhenyouviolateitsrules(forexample,uponoutofboundsarrayaccess),theseexceptionswill
helpyoufindlotsofbugs,especiallyifyoucangetthecallstackfromanexception.Ifthepurposeofanapplicationis
automatedtesting,and/orit'susedasaquickanddirtyinternaltoolasopposedtoaproductforanenduser,thiskindof
exceptionsisallyouneedtohandleerrorsofalmostallkinds.Insomelanguages,youcanevenresumetheexecutionfrom
thepointwheretheexceptionwasraisedafterfixingtheproblematthepointwhereitwascaught.

C++exceptionsoffernoneofthesefeatures."Exceptionsafe"C++codecan'thandleerrorswhichhappenwhenittriesto
releaseresources"exceptionunsafe"C++codewillleakresources,mostfrequentlymemoryandonceyouthrowan
exception,thecallstackislost.Thismeansthatevenseparatingyourcodetoseveralprocessesandexecutingcodelike*
(int*)0 = 0;uponerrorisabetterwaytohandleerrorsthanC++exceptions:atleastthememoryisgoingtobereclaimed
bytheoperatingsystem,andyoucantypicallyhaveitsaveasnapshotoftheprocess,sothatyoucanopenitinadebugger
andseewheretheerrorhappened.Arecommendationto"ban"exceptionsisprobablyovertheedge,butthinkalotbefore
usingC++exceptions,orafeaturethatimplicitlydependsonthem,suchasconstructorsandoverloadedoperators,which
havenootherwaytoreportanerror.WhatC++calls"exceptions"isasunlikelytogiveyouthebenefitspeoplegetfrom
exceptionsinotherlanguagesaswhatC++calls"classes"isunlikelytogiveyouthebenefitsofOO.

[17.2]HowcanIhandleaconstructorthatfails?
FAQ:Asyou'dguessfromthelocationofthisquestionintheFAQ,theansweris"bythrowinganexception".Alternatively,
youcanmarktheobjectasa"zombie"byusingsomekindofvalidityflag.Youcanthencheckthatflaginthecallingcode
andmaybeinthememberfunctionsoftheobject.Thelattersolutiontendsto"getugly".

FQA:TheinabilitytogracefullyhandleerrorsinC++constructorsisonegoodreasontoavoidconstructorsthatdomore
thannothing,anduseinitializationfunctionsinstead.AndC++exceptionsarenotagracefulwaytohandleerrors,especially
inconstructors.Ifyourmemberobjectconstructorthrowsanexception,andyouwanttocatchitinyourconstructor,the
normallyuglycolonsyntaxgetsmuchuglier.

Bytheway,theC++standardlibrarydoesn'tthrowexceptionsinconstructors(exceptfortheonesthrownbyoperator new).
Forexample,youaresupposedtotestwhetherofstreamobjectsarezombieswhenyoupassthemafilenameinthe
constructor.

[17.3]HowcanIhandleadestructorthatfails?
FAQ:Actuallyyoucan'tnotbeyondloggingtheproblemtoafileorthelike.Inparticular,donotthrowanexception.The
problemisthatdestructorsarecalledwhenexceptionsarethrownsothatfunctionspropagatingerrorstotheircallerscan
http://yosefk.com/c++fqa/fqa.html 61/112
2/26/2015 C++ Frequently Questioned Answers
cleanupresources.Yourdestructorcanalsobecalledinsuchasituation.Andwhenanexceptionisalreadythrown,
throwinganotheronewillresultinacalltoterminate(),killingyourprocess.Becauseyousee,whatelsecouldC++do?
There'sanambiguity:whichexceptionoutofthetwodoyouwantcaughtnow?

Strictlyspeaking,youcanmakethat"donotthrowexceptionsinadestructorunlessyouaresurethatitwon'tbecalledasa
resultofanexceptionalreadythrown",butyoucanrarelybesureofthat.

FQA:That'sright,terminate().Solomonstyleconflictresolutioncarriedtotheend.See?Exceptionsarenotagracefulway
tohandleerrors.

And"don'tthrowexceptionsindestructors"actuallymeans"don'tcallfunctionsindestructorsunlessyouaresuretheydon't
throwanexception".TheC++compilerwon'tcheckforyou,becauseitcan't:thelanguagedoesn'tforceafunctionto
declarewhetheritthrowsexceptions.

Thisisonegoodreasontoavoiddestructorsdoingmorethannothing:likeconstructorsandoperators,theycan'thandle
errors.

[17.4]HowshouldIhandleresourcesifmyconstructorsmaythrow
exceptions?
FAQ:Well,thedestructorofyourclasswillnotgetcalled,butthedestructorsofthesuccessfullyconstructedsubobjectswill
getcalled.Conclusion:youshouldhavealltheresourcesallocatedbyyourconstructorsassignedtosubobjects.For
example,ifyoucallnewinaconstructor,don'tuseabarememberpointertoholdtheresultuseasmartpointer,like
std::auto_ptr.Youcanalsodefineyourownsmartpointerclassestopointtothingslikediskrecords!Groovy!

Andyoucanusetypedeftomakethesyntaxofusingsmartpointerseasier.

FQA:WARNINGcyclicdependencybetweenC++featuresdetected!Yousee,exceptionsareamustinthislanguageso
thatyoucanhandleerrorsinallthefunctionswhichfailtolooklikefunctions,suchasconstructors&operators.Thenitturns
outthatyouneedconstructorstoworkwithexceptionsunlesseachandeverypieceofmemoryyouacquireisnot
immediatelyassignedtosomesmartpointer,yourcodeisnotexceptionsafe.Thisisknownas"ResourceAllocationIs
Initialization"(RAII)intheC++communityit'ssupposedtobeagoodthing.

Andsmartpointersarenopicnic,asarevirtuallyallautomaticdeviceswithsomethinglike"smart","simple"or"fast"intheir
name.Sure,youcanusetypedeftosimplifythesyntax.Socansomeoneelseyou'llendupwithmanydifferenttypenames
forthesamething.Thismayannoypeople,butit'sperfectlyOKwiththecompilerwhenitspitsanerrormessage,itsimply
substitutesthefulltypenamesforalltypedefnames.Butyoucanwriteaprogramtofiltertheerrormessages...

Seriously,thesyntaxofsmartpointersisthesmallproblem.Thebigproblemistheirsemantics.Whenyouseeabare
pointer,youknowhowitworks.Butasmartpointercanworkinalotofways.Theboostlibrariesallowyoutoinstantiate
hundredsofdifferentsmartpointerclassesfromasingletemplate(whichmadeittoTR1,sowe'regoingtoseeitinthenext
versionoftheC++standard).Howareyougoingtofigureoutwhetheryourprogrammanagesresourcescorrectlyornot
whenit'slitteredwithsmartpointersofdifferentkinds,especiallyincasethere'sanynontrivialscenariothere,likethecases
when"ownership"(theright&dutytodisposearesource)ispassedfromobjecttoobject,ortherearecyclicreferencesin
yourcode,orwhatever?

Wheneverysinglepieceofsoftwareis"smart",andyoucan'ttrustthingslike*pandp->x,thesoftwarebecomes
unmanageable.

[17.5]HowdoIchangethestringlengthofanarrayofchartoprevent
memoryleaksevenif/whensomeonethrowsanexception?
FAQ:Ifyouwanttoworkwithstrings,usesomethinglikestd::stringinsteadofchar*.Otherwise,there'slotsofexceptions
tocatch,andlotsofcodetomanagememory.

FQA:TheFAQisrightaboutonethingchar*isanastykindofstring,andusingitfortextprocessingisverytedious.If
you'redoinganythingnotentirelytrivialwithstrings,std::stringisbetterthanchar*usingadifferentlanguagethanC++
fortextprocessing,onewithagoodbuiltinstringtype,isstillbetter.

However,thepartwithexceptionsreallycomesfromoperator new,notfromchar*.Youcanusemallocinstead,orconfigure
yourcompilertodisableexceptions.

[17.6]WhatshouldIthrow?
http://yosefk.com/c++fqa/fqa.html 62/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:C++allowsyoutothrowobjectsofarbitrarytypeshowever,youprobablyshouldn'tthrowobjectsofbuiltintypes.For
example,youcanderiveallyourexceptionclassesfromstd::exception,andthrowtemporaryobjectsofyourclasses.

FQA:Yep,C++allowstothrowanything.Toobadyoucan'treallycatchitlater.Theonlywaytocatchanarbitraryexception
istousecatch(...),whichdoesn'tletyoufindoutwhatwasthrownfromwhere,andwillevencatchillegalmemoryaccess
onsomesystems.Thismakesfindingcodelikethrow "C++ is so grand - you can throw anything!!";alotoffun(you
havetofinditonoccasionswhentheuncaughtexceptioncrashesyourprogram).

TheFAQ'sadviceisthusagoodone,asopposedtothelanguagedecisiontoallowtothrowanythingatypicalexampleof
thetwistednotionof"generality"usedthroughoutthelanguagedesign.Thisdecisioniscompletelyincomprehensibleunless
yourealizethatthere'sabasicaxiominC++:thelanguagemustnotforcethecompilerwritertotreatanyclassspecially.For
example,havingacommonbaseclassforalluserdefinedclasseswhichhaveatleastonevirtualfunctioncouldbequite
handy,butit'sincompatiblewiththisimplicitaxiom.WhatdidtheC++designersgainfromfollowingthisbizarrerule?
Apparentlynothing,exceptforanillusionof"generality",whateverthatmeans.

[17.7]Whatdoesthrow;(withoutanexceptionobjectafterthethrowkeyword)
mean?WherewouldIuseit?
FAQ:Itmeans"throwthelastcaughtexception".Itmaybehandytocatchanexceptionobject,addsomecontext
informationandrethrowitthiswayyougetsomethinglikeastacktrace.Thisfeaturealsoallowsyoutofactoroutseveral
exceptionhandlersintoafunctioncalledfromacatch(...)block.Insidethefunction,youlistthehandlersforvarious
specialcasesandprefixthemwithtry { throw; }.

FQA:Rethrowingthelastexceptionisausefulfeature,andmanylanguageshaveit.ItwouldbeequallyusefulinC++ifC++
exceptionswereanygood.Inparticular,havingtousethiskindoffeaturethroughoutthecodetogetacallstackisaninsult
tothelanguageuser.Unlessit'ssomekindof"logical"callstack(contextinformationnotequivalenttothelistofC++
functionsyou'dseeinadebuggeratthepointwheretheexceptionwasthrown),callstacksshouldbeprovidedbythe
language.

IfyouareusingC++andwanttofigureoutthecurrentcallstack,itmaybebettertorelyonplatformspecifictricks(reading
theframepointerusinginlineassemblyandtraversingthelinkedlistpointedbyit,thentranslatingtheinstructionpointers
usingasymboltable)thantolitteryourcodewithstatementsduplicatingtheinformationthat'salreadythere.

[17.8]HowdoIthrowpolymorphically?
FAQ:SupposeyouhaveaBaseExexceptionclassandaDerivedExexceptionclass,whichisinheritedfromBaseEx.Thanthe
followingcodemightnotworkasyouexpect:
void f(BaseEx& e)
{
throw e;
}
void g()
{
DerivedEx e;
try {
f(e);
}
catch(DerivedEx&) {
std::cout << "derived exception caught" << std::endl;
}
}

Theprogramwillnotenterthecatchblockbecauseyoudidn'tthrowpolymorphically.Thatis,thestatementthrow e;throws
theobjecteasaBaseEx,becausethat'sthetypeofeinthatcontextonceanobjectisthrownasaBaseEx,itwillnotget
caughtasaDerivedEx.Ifyouprefertheotherbehavior,youcan"easilygetit"byhavingavirtual void raise() { throw
*this; }inyourbaseclassandyourderivedclass,andcallinge.raise();insteadofthrow e;.Thisway
DerivedEx::raise()iscalled,andinthecontextofthatfunctioneisoftypeDerivedEx.

FQA:Let'ssee.YouuseC++exceptions.Moreover,youhaveahierarchyofexceptionclasses.Moreover,youpass
exceptionobjectstofunctions,inawayrelyingonanimplicitupcast.Lookslikeyouhavelotsofconfidenceinyour
knowledgeofC++features.ButalongcomesC++andbeatsyourcommonsenseonceagain.Thestartlinginconsistencyof
thelanguageisalmostavirtue:maybethistimeyouwilllearnthevalueofsimplicityandwritesomethingreadable.

Thebehaviorofthrow,whichlooksatthestatictypeofitsargumentexpression,issomewhatsurprisingconsideringthe
behaviorofcatch,whichdoes"respect"inheritance(totheextentmadepossiblebythrow).Inpractice,itisprobablybetter
toremovesomeofthecomplexityintheexampleratherthanaddmorecomplexitybymixingthedynamicbindingofvirtual
withthestaticbindingofthrow.Ahumanmightneedtounderstandthecode,youknow.
http://yosefk.com/c++fqa/fqa.html 63/112
2/26/2015 C++ Frequently Questioned Answers
IfyoudowanttomemorizethequirksofC++,trytowarpyourmindtothinkintermsusedbythecompilerconstruction
peanutgallery.Fromthisperspective,thebehaviorofthrowandcatchisconsistent:bothonlylookatthingsknownat
compiletime(therelationshipsbetweenclasses),andignorethingsonlyknownatruntime(theactualtypeofanobject).
BasicallyallofC++behavesthiswayexceptforvirtual,dynamic_castandtypeid.Ithink.

[17.9]WhenIthrowthisobject,howmanytimeswillitbecopied?
FAQ:Zeroormore.There'snouniversalanswer.Thecompilerhastomakesureathrownobjectprovidesacopy
constructor,evenifitdoesn'tactuallycopyanything.

FQA:Ifyoucareaboutperformance,C++exceptionsareprobablynogoodforyou.Exceptionsupporttranslatestoahuge
mountainofcodeinyourexecutable,andslowsdownfunctioncallsthroughoutyourprogram.Ifyoudidn'tcareabout
performance,youwouldn'taskthisquestion.Ifyouthinkthatyoucareaboutperformance,butneveractuallymeasureitor
lookattheperformanceimplicationsofthetechniquesyouuseinyourcode,feelfreetoentertainyourselfwithanyfake
answerthatsuitsyouremotionalneeds.

[17.10]ExceptionhandlingseemstomakemylifemoredifficultclearlyI'm
nottheproblem,amI??
FAQ:Ofcourseyoucanbetheproblem!

HerearesomehabitsthatmaypreventyoufromutilizingthepowerofC++exceptionhandling:

Returncodesstyle:peoplemayputtryblocksaroundeveryfunctioncallasifexceptionswereerrorcodes.
TheJavastyle:usingtry/finallyinsteadofRAII,clutteringthecodewithcleanupstatements.
Organizingexceptionsaroundthelocationoftheerrorratherthanitsreason:thiswayyouneedtohandlethesame
errormanytimesandconvertbetweentypesofexceptions.
Categorizingerrorsusingdatamembersofexceptionclassesratherthantypes:thiswayyoucatchmoreerrorsthan
youcanhandleinthegivencatchblocks,andrethrowexceptionsafteratest.
Usingdifferentexceptionclassesindifferentsubsystems:theFAQdecidestorepeatthepointbeforeprevious,
probablytocreateanimpressionthattherearesomanywrongmindsetsoutthere.
Usingbarepointersinsteadofsmartpointerclasses:aspecialcaseofavoidingRAII,admitstheFAQ,butitcan'tfight
thetemptationtolistyetanother"wrongmindset".
Confusingbugswithruntimeerrors:ifsomeonepassesanullpointertoafunctionwhenthat'sillegal,thecodemust
befixed.Throwinganexceptionwithoutfixingthecallingcodedoesn'tsolvetheproblem.

Thereareotherwrongmindsetsaswell.

FQA:Yeah,youknowhowitiswiththosehumans.Theyalwaysfailtorealizetheyaretheproblem,andkeepaskingthe
wrongquestions.Yougivethemahelpfulandpowerfullanguage,andalltheydoisshootingthemselvesinthefeet.Clearly
it'stheirflawedmindsthatmustbefixed.

Let'slookalittlecloserattheimpressivelistof"wrongmindsets"compiledbytheFAQ:

Returncodesstyleissurelyawrongwaytouseexceptions,butit'soneofthebestwaystouseC++exceptions,
becauseotherwisethechancetomanageresourcescorrectlyisnotveryhigh.Ofcourseusingrealreturncodesis
somewhatcleaner,butwhatifexceptionsarethrownbythirdpartylibraries?
TheJavastyleissuitedquitewelltoamanagedenvironmentlikeJava,becausemostofthesocalledresourcesarein
factmemory,andyouonlyneedtry/finallyblocksforstufflikefiles,ofwhichtherearefew.Thisstyleisproblematicin
C++whichlacksgarbagecollection,butsoisRAIIwhichforcesyoutowrapeverythingwith"smartpointers"ina
languagewhichonlyhasbuiltindumbpointers.ThetruthisthatwithC++exceptions,youcan'twin.
Organizingexceptionsaroundthelocationoftheerrorratherthanitsreason:supposeyouhave2parsersinyour
system.WouldyoupreferasingleParseErrorexception,or2separateclasses,HtmlParseErrorand
ConfigFileParseError?Twodifferentmodulesmayraiseexceptionsforsimilarreasons,butrarelythesamereason
orelsewhyaretheydifferentmodules?Anobviousexceptiontothisruleareerrorsdetectedatthelanguagelevel,
thingslikeArrayIndexOutOfBoundsException.Luckily,theC++languageruntimeenvironmentdoesnotdetecterrors,
sowedon'tneedtodiscussthiskindofthing.
Categorizingerrorsusingdatamembersofexceptionclassesratherthantypesisnotnecessarilybad.C++iscentered
aroundtheassumptionthatyoucanrepresentalmostanythingusingtypes(classhierarchiesortemplate"pattern
matching")morethananyotherpopularstaticallytypedlanguage.However,thisassumptionisfrequentlyrefutedby
reality,andstickingtoitiscounterproductiveinmanycases.Forinstance,ifasubsystemthrowsexceptionsofa
singleclass,andyoufigureoutthekindoferrorfromlookingattheobjectmembersoreveninspectingerrorstrings,
youmayendupwithlessproblemscomparedtothecasewhereyouhaveseveraldozensofclassesinyourexception
inheritancetree.Thisisaspecialcasewheremodelinganaspectofyourprogramusingthelanguagestatictype
http://yosefk.com/c++fqa/fqa.html 64/112
2/26/2015 C++ Frequently Questioned Answers
systemmayormaynotbeoptimal.
Usingdifferentexceptionclassesindifferentsubsystems:WOW,thisissonasty!Ofcourseallsubsystemsshould
shareexceptionclassesandotherimportantcommontypes.Allsubsystemsofallsystemsintheworldshouldbe
writteninclosecoordinationbetweentheimplementers.Thisway,we'llfinishtheTowerofBabelinnotime!That'swhy
alanguageshouldhavenogoodwaytopassanobjectofarbitrarytypethrougha"subsystem".Trustus:wearethe
peopleadvocatingalanguagewithoutacommonstringtype.Wesureknowathingortwoabouttheissue.
Usingbarepointersinsteadofsmartpointerclasses:howaboutstaringwiththelanguageandthestandardlibrary?
Whenoperator newreturnsasmartpointer,and"abc"hasthetypestd::string,we'llhavesomethingtodiscuss.Until
then,whyshouldanyonemanuallyemulateahighlevellanguageontopofalowlevelonethroughoutone'scode?
Confusingbugswithruntimeerrors:thishasabsolutelynothingtodowithexceptions.It'sequallyapplicabletoanyrun
timeerrorhandlingstrategy.Unless,ofcourse,yourenvironmentthrowsexceptionsuponeventslikenullpointer
dereferencing,whichC++doesn't.

[17.11]IhavetoomanytryblockswhatcanIdoaboutit?
FAQ:Maybeyouhavea"returncodesmindset"eventhoughsyntacticallyyouuseexceptions.Therearemanyspecial
casesofthisprobleminwhichyoucanorganizethecodedifferentlytoreducetheamountoftryblocks(theFAQlists
severalcases).Ifyoucan'tsolvetheproblemyourself,getamentor.

FQA:Alternatively,youcanstopthrowingC++exceptionssoyouwon'thavetocatchthem.

Constcorrectness
Thisisabouttheconstkeyword,whichmakesyouwriteyourprogramtwice(ormore,dependingonyourluck).

[18.1]Whatis"constcorrectness"?
[18.2]Howis"constcorrectness"relatedtoordinarytypesafety?
[18.3]ShouldItrytogetthingsconstcorrect"sooner"or"later"?
[18.4]Whatdoes"const Fred* p"mean?
[18.5]What'sthedifferencebetween"const Fred* p","Fred* const p"and"const Fred* const p"?
[18.6]Whatdoes"const Fred& x"mean?
[18.7]Does"Fred& const x"makeanysense?
[18.8]Whatdoes"Fred const& x"mean?
[18.9]Whatdoes"Fred const* x"mean?
[18.10]Whatisa"constmemberfunction"?
[18.11]What'stherelationshipbetweenareturnbyreferenceandaconstmemberfunction?
[18.12]What'sthedealwith"constoverloading"?
[18.13]WhatdoIdoifIwantaconstmemberfunctiontomakean"invisible"changetoadatamember?
[18.14]Doesconst_castmeanlostoptimizationopportunities?
[18.15]WhydoesthecompilerallowmetochangeanintafterI'vepointedatitwithaconst int*?
[18.16]Does"const Fred* p"meanthat*pcan'tchange?
[18.17]WhyamIgettinganerrorconvertingaFoo**toconst Foo**?

[18.1]Whatis"constcorrectness"?
FAQ:Oh,that'sagreatthing.Youdeclareanobjectasconstandpreventitfrombeingmodified.

Forexample,ifyoupassastd::stringobjecttoafunctionbyconstpointerorreference,thefunctionwon'tmodifyitandit
won'tbecopiedthewayithappenswhentheobjectispassedbyvalue.

FQA:Interesting.Whataboutvectorofpointerstoobjects?Let'ssee.Ifthevectoritselfisdeclaredconst(asinconst
std::vector<T*>),thenyoucan'tmodifythevector,butyoucanmodifytheobjects.Ifthepointersaredeclaredconst(asin
std::vector<const T*>),thenyoucanmodifythevector,butnottheobjects.Nowsupposeyouhaveavectorofnonconst
objects,andyouwanttopassthemtoafunctionthatacceptsaconstvectorofconstobjects.Oops,can'tdothatthe
vectorsaretwodifferentunrelatedtypesasfarasthecompilerisconcerned(no,C++weenies,itactuallydoesn'tmake
sense,thinkagain).You'llhavetocreateatemporaryvectoroftherighttypeandcopythepointers(whichwillcompilejust
finesinceT*issilentlyconvertibletoconst T*).

That'swhatconstcorrectnessisallabout:increasingthereadabilityofyourprogramandprotectingyoufromerrorswithout
anyperformancepenalties.

Bytheway,notusingconstinC++isquitelikelynotaverygoodidea.OfallquestionableC++features,constprobably
doesthemostvisibledamagewhenavoided.Anypieceofcodeusingconstforceseveryotherpiecetouchingittouse
http://yosefk.com/c++fqa/fqa.html 65/112
2/26/2015 C++ Frequently Questioned Answers

const,orelseyouwon'tbeabletoworkwiththeobjectsitgivesyou.Andhere'sthefunnypart:everypieceofcodenot
usingconstforceseveryotherpiecetouchingittonotuseit,eitherorelseyouwon'tbeabletopassobjectstoit.Soifyou
haveoneconstparticleandoneanticonstparticle,there'sabigshinyexplosionofconst_castinyourcode.Sinceconstis
hardwiredintothelanguage(nowaytopassatemporarytoafunctionthatgetsanonconstreference,forexample)and
thestandardlibrary(iteratorandconst_iterator),usingconstisusuallyasaferbetthanavoidingit.

[18.2]Howis"constcorrectness"relatedtoordinarytypesafety?
FAQ:It'soneformoftypesafety.Youcanthinkaboutconst std::stringasanalmostseparatetypethatlackscertain
operationsofastring,likeassignment.Ifyoufindtypesafetyuseful,you'llalsolikeconstcorrectness.

FQA:It'srelatedtoordinarytypesafetyinaprettycomplicatedway.constandvolatilearespecialcasesinthetype
systemtheyare"typequalifiers".Therelationbetweenaqualifiedtypeandanonqualifiedtypeisdifferentfromanyother
relationbetweentypesinthelanguage.Thisisoneoftheverymanycomplicationsintheimplicitconversionandoverload
resolutionrules.

Itworkssmoothlyforthesimplecases,especiallyiftherearenoothercomplications.Itbreaksprettyhardwheneveryou
haveapointerlikeobject.Pointerscangettwoconstqualifiers,oneforthepointerandoneforthepointedvalues.Thisis
awkwardandunreadableandwhenyouhavepointerstopointersandthreeconstqualifiers,youmayneedcrypticexplicit
casts,butatleastthere'ssyntaxforallthelevelsofconstness.With"smartpointers"(thethingsyoushouldstuffintoevery
possibleholebecausepointersareevil),there'snosuchsyntax.That'swhywehaveiteratorandconst_iteratorsaying
const iteratorsaysthattheiteratorisimmutable,butnotwhatitpointsto.Exercise:implementavectorlikeclassthatcan
getthestoragepointerfromtheuser,inaconstcorrectwaythatsupportsattachingbothtoconstantandmutablestorage
areas.

Andofcourseavectorofconstpointersiscompiledtoadifferentbulkof(identical)assemblycodethanavectorofmutable
pointers.Atleastherethecompileriswritingthesameprogramtwice,whichisbetterthanhavingtodothisyourself.Which
alsohappensconst_iteratorisonefamilyofexamples.

[18.3]ShouldItrytogetthingsconstcorrect"sooner"or"later"?
FAQ:Assoonaspossible,becausewhenyouaddconsttoapieceofcode,ittriggerschangesineveryplacerelatedtoit.

FQA:That'sright.Sinceyoucan'tgetoutofthetarpit,thebeststrategyistoclimbrightintothemiddleandmakeyourself
comfortablefromthebeginning.Nokidding,IactuallyagreewiththeFAQ.Seealsotheadviceaboveaboutnotavoiding
const.

[18.4]Whatdoes"const Fred* p"mean?


FAQ:Apointertoaconst Fredobject.Theobjectcan'tbechanged,forexample,youcan'tcallmethodsnotqualifiedas
const.

FQA:Right.Butdon'tcountonitwhenyoudebugcode.constcanbecastawayinasnap(prettymuchlikeeverythingelse
inC++),andthere'sthemutablekeywordforcreatingmembersthatcanbemodifiedbymethodsqualifiedasconst.Andof
coursesomeonecanhaveanother,nonconstpointertothesameFredobject.Andtheconstqualifiedmethodsmaymodify
datapointedbyitsmemberpointersandreferencesorbypointerskeptinthingspointedbyitsmemberpointers,etc.

Thepointeraliasingissueisonereasonthatthecompilercan'treallyoptimizecodebecauseitseesapointerdeclaredas
const.Andwhenitcanfigureouttherearenoaliases,itdoesn'tneedyourconstdeclarationstohelpit.Youcanexplainthe
differencebetweendataflowanalysisandtypequalificationtothenextpseudoperformanceawarepersonwhoadvocates
declaringeverylocalintegerasconst.SeealsoacorrectFAQanswertothisquestionbelow.

[18.5]What'sthedifferencebetween"const Fred* p","Fred* const p"and


"const Fred* const p"?
FAQ:Inthefirstexample,theobjectisimmutable.Inthesecondexample,thepointerisimmutable.Inthethirdexample,
bothareimmutable.

FQA:Um,right.Remember:constmakesyourprogramsreadable.

[18.6]Whatdoes"const Fred& x"mean?

http://yosefk.com/c++fqa/fqa.html 66/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:It'sareferencetoanimmutableFredobject.

FQA:WhichissimilartoapointertoanimmutableFredobject.However,theFAQholdsthe"referencesareNOTpointers"
religion(specifically,itbelongstothe"pointersareevil"faction),soitdutifullyreplicatestheexplanationgivenintheanswer
aboutthepointercase,replacing"pointer"with"reference".

[18.7]Does"Fred& const x"makeanysense?


FAQ:No.Itsaysthatyoucanchangetheobject,butnotthereference.Butyoucanneverchangeareferenceanyway,itwill
alwaysrefertoasingleobject.

Don'twritesuchdeclarations,itconfusespeople.

FQA:Sowhydoesthiscompile?Wait,Idon'treallywanttoknow.Whetherit'sbecausetheydidn'tbothertodisallowit,or
becausesomespecialcaseoftemplateinstantiation(likewhenyouaddaconsttoaparametertypewhichisinfacta
reference)wouldfailoranythinglikethatthat'sjustanotherlameexcuseasfarasalanguageuserisconcerned.

[18.8]Whatdoes"Fred const& x"mean?


FAQ:It'sequivalentto"const Fred& x".Thequestioniswhichformshouldyouuse?Nobodycananswerthisforyour
organizationwithoutunderstandingyourneeds.Thearelotsofbusinessscenarios,someproducingtheneedforoneform,
othersfortheother.Thediscussiontakesafullscreenoftext.

FQA:Yawn.AnotherstupidduplicationinC++.

Comeon.What"businessscenarios"can"produceneeds"foraformofaconstdeclaration?Ifyourorganizationemploys
peoplewhocan'tmemorizebothformsorcheckwhatadeclarationmeans,youhavetoadmittheywilldrowninC++evenif
yousomehowknowforsurethatingeneraltheycanprogram.C++hasmegatonsofsyntax.

[18.9]Whatdoes"Fred const* x"mean?


FAQ:TheFAQreplicatesthepreviousanswer,replacing"reference"with"pointer".Probablythesamereligionthingagain.

FQA:Yawn.AnotherstupidduplicationintheC++FAQ.

[18.10]Whatisa"constmemberfunction"?
FAQ:It'sdeclaredbyappendingconsttotheprototypeofaclassmemberfunction.Onlythiskindofmethodsmaybecalled
whenyouhaveaconstobject.Errorsarecaughtatcompiletime,withoutanyspeedorspacepenalty.

FQA:Asdiscussedabove,thisbreaksintolittlepieceswhenyourclassissimilartoapointerinthesensethatausercan
changeboththestateofyourobjectanduseyourobjecttochangesomeotherstate.Astothespeedandspacepenalty,
youmaycheckthesymboltableofyourprogramifyouwanttoknowhowmanyfunctionsweregeneratedtwicefroma
singletemplatebecauseofconstandnonconsttemplateparameters.Thenyoucancountthefunctionshavingidentical
codeexceptforextraconstqualifiersinsomeversions,butnotothers.

[18.11]What'stherelationshipbetweenareturnbyreferenceandaconst
memberfunction?
FAQ:constmemberfunctionsreturningreferencestoclassmembersshoulduseaconstreference.Manytimesthe
compilerwillcatchyouwhenyouviolatethisrule.Sometimesitwon't.Youhavetothink.

FQA:Ofcourseyouhavetothinkaboutthiscompleteandutternonsense!Somebodyhasto,andtheC++designersdidn't.

Asusualwithconst,thecompilerbecomesdumbwhenlevelsofindirectionappear.Forinstance,ifyoukeepamember
reference,thethingitpointstoisnotconsideredpartoftheobject.It'suptoyoutodecidewhetheryouwanttoreturnthis
referenceasconstornonconstfromyourconstmemberaccessor.Bothchoicesmayeventuallyleadtoconst_cast.

[18.12]What'sthedealwith"constoverloading"?
FAQ:Youcanhavetwomemberfunctionswithasingledifferenceintheprototypethetrailingconst.Thecompilerwill

http://yosefk.com/c++fqa/fqa.html 67/112
2/26/2015 C++ Frequently Questioned Answers
selectthefunctionbasedonwhetherthethisargumentisconstornot.Forinstance,aclasswithasubscriptoperatormay
havetwoversions:onereturningmutableobjectsandonereturningconstobjectsinthelatterversion,thisisalsoqualified
asconst.

FQA:Pleasetrytoavoidthisfeature.Inparticular,getandsetfunctionshavingthesamename(constoverloaded)arenota
verygoodidea.

Havingtoreplicatethecodeofasubscriptoperatorjusttoaddtwoconstqualifiersforthereturnvalueandthethis
argumentisyetanotherexampleofconstforcingyoutowriteyourprogramtwice.Well,mostlikelytherearemore
problemswherethisonecamefrom.Aclasswithasubscriptoperatorisa"smartarray",probablynotunlikestd::vector,so
you'llendupwithmuchmorereplicatedcodeaniteratorandaconst_iteratororsomesuch.

[18.13]WhatdoIdoifIwantaconstmemberfunctiontomakean"invisible"
changetoadatamember?
FAQ:Therearelegitimateusecasesforthisthatwouldbewhenauserdoesn'tseethechangeusingtheinterfaceofthe
class.Forexample,asetclassmaycachethelastlookuptopossiblyspeedupthenextlookup.

Usethemutablekeywordwhenyoudeclarethemembersyouwanttochangethisway.Ifyourcompilerdoesn'thave
mutable,useconst_cast<Set*>(this)orthelike.However,trytoavoidthisbecauseitcanleadtoundefinedbehaviorifthe
objectwasoriginallydeclaredasconst.

FQA:Mostcompilersprobablysupportmutabletoday,butyoumaystillneedconst_castbecausethetweakstothetype
systemsupportingconstbreakinmanycases.Whichmaybeaproblemcombinedwiththefactthatconst_castisnot
designedtoworkwithobjectsdeclaredasconst(asopposedtothosedeclarednonconstantbutpassedtoafunctionby
constreferenceorpointer).

Therearenumerousreasonsmakingconst_castsaferinpracticethanintheory.Peoplerarelydeclareobjectsasconst.
CompilerwritersareunlikelytoaddspecialcasestotheircompilertosupportconstobjectsofC++classesbecauseit'shard
workthatisunlikelytopayoff.Forexample,allocatingaglobalconstCstylestructurewithanaggregateinitializerinread
onlymemoryiseasy.DoingthesameforaC++classwithaconstructorishardbecausetheconstructormustbeableto
writetotheobjectuponinitialization.Soyou'dhavetousewritablememoryyoulatermakereadable,whichisnottypically
supportedbyobjectfileformatsandoperatingsystems.OryoucouldtranslateC++codetoaCstyleaggregateinitializer,
spendinglotsofefforttoonlyhandlethecaseswhenthecompilercaninlinethecodeoftheconstructors.

However,thereisnosimplerulemakingit"veryclosetoimpossible"foracompilerwritertousetheopportunityprovidedby
thestandardandimplementconstobjectsdifferentlyfromotherobjects.Inthecaseofoptimizingthedereferencingofconst
pointers,sucharuledoesexist(theremightbeother,nonconstpointerstothesamelocation).Butinthecaseofobjects
declaredconst,thereshouldbenosuchpointers.

Thefactthatthecompilerisallowedtoworkunderthisassumptioncouldbegreatifitweremorelikelytoactuallyyield
performancebenefits,andifconstworkedtoanextentmakingtheuseofconst_castunnecessary.Thecurrentstateof
affairsjustcreatesanothersourceofuncertaintyfortheprogrammer.

[18.14]Doesconst_castmeanlostoptimizationopportunities?
FAQ:Theoretically,yes.Inpractice,no.Ifacompilerknowsthatavalueusedinapieceofcodeisnotmodified,itcan
optimizetheaccesstothatvalue,forexample,fetchittoamachineregister.However,thecompilercan'tbesurethata
valuepointedbyaconstpointerisnotmodifiedbecauseofthealiasingproblem:therecanbeotherpointerstothesame
object,notnecessarilyconstant.Provingtheoppositeisalmostalwaysimpossible.

Andwhenthecompilercan'tproveit,itcan'tspeeduptheaccesstothevalue.Forexample,ifitusesthevalueitfetchedto
aregisteraftersomeonemodifieditintheoriginalmemorylocation,thecompilerchangesthemeaningoftheprogram
becauseitusesanoutdatedvalue.

FQA:ThreecheerstotheFAQ!No,really,thistimetheanswerdescribestheactualstateofaffairs.YouunderstandwhyI'm
sodeeplytouchedifyoumetsomeofthemanyC++userswhogiveadifferentanswertothisquestion,andknowtheirways
toreasonaboutperformance.

Ithinktheansweris"no"intheory,too,becausebasicallythecompilerhastofigureoutwhichpartsofthecodemodifythe
data,andifitknowsthedatawon'tgetmodifiedwhilethispieceofcodeisrunning,itcanusethisfact,andotherwiseitcan't,
sowhatdifferencedoyourconstqualificationsmake?Butlet'ssayI'mnotreallysure,andanyway,it'snotthetimetoargue
abouttheexactphrasingwhenonceinalifetimearealisticstatementappearsabouttheperformanceofC++code.

Thethingthatisworthnotingisthataliasingproblemsimpedetheperformanceof"generic"libraries,notjustcompilers.For
http://yosefk.com/c++fqa/fqa.html 68/112
2/26/2015 C++ Frequently Questioned Answers
example,considervector<T>::push_back().Thevectorwilltrytoappendtheobjecttoitsstorage.Ifthere'snofreespace
left,itwillallocatealargerchunk,copytheoldobjects,andthenappendthenewone.Thenewobjectisthuscopiedonce
(fromwhereveritwasintothevectorstorage),right?

Butwhatiftheobjectisitselflocatedintheoldchunk,andvectortriestobeefficientanduserealloc,whichmayormaynot
freetheoldmemory?Theobjectmaybewipedoutbyrealloc.Verygood,then,vectorcreatesanothercopy.Hop1from
theparametertoatemporary,hop2fromatemporarytothevectorstorageandeveryoneishappyafteracertainamount
ofclockcycles.

"Theoretically,yes.Inpractice,no."QuiteanicesummaryofC++.

[18.15]WhydoesthecompilerallowmetochangeanintafterI'vepointedat
itwithaconst int*?
FAQ:Becausewhenyoupointtosomethingwithaconstpointer,thisonlymeansthatyoucan'tusethatpointertochange
theobject.Itdoesn'tmeantheobjectcan'tbechangedatall,becauseitcanbeaccessibleinotherways,notonlythrough
thispointer.

FQA:Exactlyit'srelatedtothepreviousFAQ.SurprisinglyforC++,itevenmakessense.Afterall,whentheobjectis
declared,itseemsliketherightplacetosaywhatcanbedonewithit.Butifanyonecantakeanexistingobjectandpointto
itandthusredefinewhatcanbedonewithit,it'sjustweird,andcan'treallywork,becauseitcouldbedonefrommany
placesinincompatibleways.

[18.16]Does"const Fred* p"meanthat*pcan'tchange?


FAQ:No,forexample,itcouldchangethroughanonconstantFred* qpointingtothesameobject.

FQA:Thisquestionisjustlikethepreviousone.

[18.17]WhyamIgettinganerrorconvertingaFoo**toconst Foo**?
FAQ:Itwouldbe"invalidanddangerous"!SupposeFoo**pointstoanarrayofpointers,whichcanbeusedtomodifythe
pointedobjects.SupposeC++wouldallowtopassthisarraytoafunctionwhichexpectsconst Foo**anarrayofpointers
whichcan'tbeusedtomodifythepointedobjects.

Nowsupposethatthisfunctionfillsthearraywithabunchofpointerstoconstantobjects.Thislooksperfectlygoodinthat
context,becausethat'swhatthefunctionwaspassedanarrayofpointerstoconstantobjects.Butwhatwe'vegotnowis
anarrayofpointerswhichcanbeusedtomodifythoseconstobjects,becausethedeclarationofthearraydoesallowsuch
modifications!

It'sagoodthingwegetacompiletimeerrorinstead.Don'tusecaststoworkaroundthis!

FQA:Wonderful.Butwhyarewediscussingevilbuiltinpointersanyway?Let'stalkaboutthesmartC++arrayclasses.Why
can'tIpassstd::vector<T*>&toafunctionexpectingconst std::vector<const T*>&?Thefunctionclearlysaysthatit'snot
goingtomodifyanything:neitherthevectornorthepointedobjects.Whycan'tIpassmymutablevectorofmutableobjects
toafunctionthatpromisesnottomodifyeitherofthose?

Inheritancebasics
ThissectionoutlinestheC++"support"fortheOOconceptofinheritance.DonotconfuseC++andOO.

[19.1]IsinheritanceimportanttoC++?
[19.2]WhenwouldIuseinheritance?
[19.3]HowdoyouexpressinheritanceinC++?
[19.4]IsitOKtoconvertapointerfromaderivedclasstoitsbaseclass?
[19.5]What'sthedifferencebetweenpublic,private,andprotected?
[19.6]Whycan'tmyderivedclassaccessprivatethingsfrommybaseclass?
[19.7]HowcanIprotectderivedclassesfrombreakingwhenIchangetheinternalpartsofthebaseclass?
[19.8]I'vebeentoldtoneveruseprotecteddata,andinsteadtoalwaysuseprivatedatawithprotectedaccess
functions.Isthatagoodrule?
[19.9]Okay,soexactlyhowshouldIdecidewhethertobuilda"protectedinterface"?

http://yosefk.com/c++fqa/fqa.html 69/112
2/26/2015 C++ Frequently Questioned Answers

[19.1]IsinheritanceimportanttoC++?
FAQ:Sure.That'sthenewthingOOaddsontopofthemorebasicnotionofabstractdatatypes.

FQA:Itis,butforaslightlydifferentreason.C++usesinheritancetoimplementruntimepolymorphismallowtousetwo
objectsofdifferentclassesinthesameway.Inorderforthistowork,theclasses(veryroughly)mustbeinheritedfroma
commonbaseclass.

Itisalsopossibletoimplementpolymorphismwithoutinheritance.Thesystemmaysimplyallowyoutocallthemethodsof
anobjectwithoutknowingitstype,andthecodewillworkifandonlyiftheobjectactuallyhasthemethodswiththeright
nameandarguments.Suchsystemsmaystillsupportinheritance,butit'slesscentralforthem.

OOsystemsencouragingpolymorphismoftheformerkindaresaidtobe"staticallytyped"inthesensethatyouuseobjects
throughexplicitlydefinedinterfaceswhicharevisibleatcompiletime.Thisapproachiswellestablishedandhasmanypros
andcons(sodoestheotherapproach).TheC++choicetousethisapproachis"legitimate"inthesensethatitcanyielda
relativelyusable&consistentresult.

However,C++inheritanceisdesignedtosupportmanyotherthings,leadingtoalessusableandlessconsistentresult.In
particular,inheritancecomplicatesthealreadycomplicatednamelookupinmanywaysuniquetoC++,andmultiple
inheritanceisquiteamess.Ontheotherhand,manyhandyfeaturesareleftout,forexample,therearenomultimethodsor
dynamictypeinformationallowingtolisttheinterfacessupportedbyaclass(thelatterisaspecialcaseoflackingreflection).

[19.2]WhenwouldIuseinheritance?
FAQ:Asatoolforspecifyingthebehaviorofasystem.Peoplethinkintwodimensions:"isa"and"hasa".Forinstance,a
cat"isa"mammaland"hasa"tail.Aggregationofdataintoabstractdatatypessupportsthe"hasa"dimension.Inheritance
addssupportforthe"isa"dimension.

FQA:Whenappropriate.TheFAQitselfdoesaprettygoodjoblistingsituationswhensomething"isa"somethingelseonan
intuitivelevel,butusinginheritanceisstillwrong.Inheritanceisaformalconcept,andformalconceptsdon'tmapdirectlyto
Englishwords.

Nobodyknowsthenumberofdimensionspeopleusetothinkyet.Forexample,imagineablackcat.Doesit"havea"black
coloror"isa"blackobject?Whatifit'sunderatabledoesit"havea"tableaboveitor"isa"thingunderatable?Nobody
knowswhat"thinking"is,andnaturallanguagecannotbereducedtoacoupleofdimensions.It"has"anunknownnumber
ofdimensions.It"isa"thingwithanunknownnumberofdimensions.Whatever"dimension"means.

Aprogramminglanguageisatoolpeopleusetoprogrammachines.Evenifweknewhowthinkingworks,andwecould
builda"thinkingmachine",we'dstillneedprogramminglanguagesfortheothermachines.Theonesthataresupposedtodo
whattheyaretold,quickly,reliablyandcheaply,asopposedtothosesupposedtobecreativethinkers.Andaprogramming
language,whichmustbeprecise,cannotmapdirectlytoanaturallanguage,whichisnot.

Touseinheritanceoranyotherformaldevice,youhavetounderstandexactlyhowitworks.Luckily,inmostprogramming
languagesit'sreasonablyeasy.AndwithC++,youcanatleasttrytorestrictyourselftothesubsetyoudounderstand.

[19.3]HowdoyouexpressinheritanceinC++?
FAQ:Byusingthe: publicsyntax,asinclass Car : public Vehicle { ... };.privateandprotectedinheritanceare
different.

FQA:Yeah,verydifferent:replacethepublickeywordwiththeprivateorprotectedkeyword.TheFAQprobablymeans
thattheyaredifferentbecausetheyarelessrelatedtoOOsemantically.

Youmaywonderwhatthecolonsyntaxhastodowiththeconceptofinheritance.Well,theconnectionisobvious:there'sno
inheritanceinC,andaddingkeywordstoC++reducesthe"compatibility"withC,becausethegrammarsoftheselanguages
preventyoufromusingkeywordsasidentifiers.Onceagain,punctationcomestotherescue.Theothertechniqueforretro
fittingfeaturesintothegrammarisoverloadingkeywords(considerstatic).

Tobefair,manylanguageshavethisproblemwiththeirgrammar,andit'snotaverybigdeal.

[19.4]IsitOKtoconvertapointerfromaderivedclasstoitsbaseclass?
FAQ:Forpublicinheritanceyes.Bydefinition,anobjectofaderivedclassisanobjectofthebaseclass.

http://yosefk.com/c++fqa/fqa.html 70/112
2/26/2015 C++ Frequently Questioned Answers
FQA:Moreover,ifyoudon'tthinksomeoneisgoingtodothis,oryouknowit'snotgoingtoworkasexpected,don'tuse
inheritance.Thewholepointofinheritanceistoallowexactlythat:tohavecodethatworkswithobjectsofabaseclassand
infactcanbepassedobjectsofarbitraryderivedclasses.Ifmakingthispossibleisnotwhatyouwant,inheritancedoesn't
reallyhelpyouandwillconfusetheusersofyourclasses.

Ofcoursepublicinheritanceisalsousedformindnumbingtemplatemetaprogrammingtricks,likehavingatemplatederive
fromitsowninstantiationrecursively,orfromatemplateargument.Thejudgmentofwhetherthisisareasonableusageofa
languagefeatureislefttothereader.

[19.5]What'sthedifferencebetweenpublic,private,andprotected?
FAQ:privateisforclassmembersandfriends.protectedisalsoforderivedclassesandtheirfriends.publicisfor
everybody.

FQA:Exactly.Theonlyparthavingtodowithinheritanceisprotected,andit'susefulrelativelyrarely.

[19.6]Whycan'tmyderivedclassaccessprivatethingsfrommybaseclass?
FAQ:Itprotectsyoufromchangestothebaseclassbynotlettingyourelyonitsimplementationdetails.

FQA:However,itdoesn'tprotectyoufromrecompilationofyourderivedclasseswhenchangesaremadetothebaseclass
(accesscontrolkeywordsarelittlemorethancommentsinC++).Keepthatinmindwhenyoudesigninterfaces,especially
thosewhicharesupposedtobeusedoutsideofyourteam.IfyouwanttosupplyC++interfaces,whichisprettydaringby
itself,notexposinganybaseclassesexceptpureabstractones(thosehavingnodatamembers)maybeagoodidea.

[19.7]HowcanIprotectderivedclassesfrombreakingwhenIchangethe
internalpartsofthebaseclass?
FAQ:Yourclasshastwointerfaces:publicandprotected.Toprotectyourusers,don'texposedatamembers.Similarly,
youcanprotectthederivedclassesbynothavingprotecteddatamembersprovideprotected inlineaccessorsinstead.

FQA:DearDesignGuru!Listencarefully,andtrytounderstand.

One.Writinggetandsetfunctionforeverymembertakestime,andsodoesreadingthem.Thistimecaninsteadbeusedto
getsomethingdone.

Two.Ifyoucangetandsetamember,it'sprettyclosetobeingpublic.Anynontrivialrepresentationchangebecomes
impossiblesincetheabilitytosetthisparticularmemberisnowapartofthecontract.

Three.Havingpropertiesinthelanguagethingsthatlooklikemembersbutareinfactaccessorsdoesn'thurt.Many
languageshaveit,allowingtouseplainmembersandinthe0.1%ofthecaseswhenyourclassbecomesverypopularand
youwanttochangeitandyoucandoitwithoutbreakingthecontract,youcanmakethememberaproperty.There'sno
reasonfornothavingthisinC++that'sevenremotelyinterestingtoalanguageuser.

IfyouknowC++programmerswhoareobsessedwithuselesswrappercodeandperformancetheynevermeasure,the
protected inlinepartiskindafunny.

[19.8]I'vebeentoldtoneveruseprotecteddata,andinsteadtoalwaysuse
privatedatawithprotectedaccessfunctions.Isthatagoodrule?
FAQ:No,no,no"always"rulesdon'tworkintherealworld!Youdon'thavetimetomakelifeeasyforeveryone.Spend
yourtimemakingiteasyfortheimportantpeople.Peoplearenotequal.Theimportantpeoplearecalled"customers".

FQA:Thanks,that'sjustwhatIneeded!Youknow,Iwasgoingtomakelifeeasierforeveryonebywritinghordesofgetand
setfunctions.ButnowIcanprioritizeandonlymakelifeeasierfortheimportantpeople.

Pleaseyourcustomersbywriting56%moregetandsetfunctionsthanyourcompetitorusingthenewestVisualRefactoring
Tooltoday!

Actually,theFAQdoesmentionthatyou'llprobablyneedmorethangetandsetfunctionstoreally"protectthederived
classesfromchanges".Butthebasicassumptionthatlotsoflayersmakelifeeasywhenyouhavetimetocreateallthose
layersisstillridiculous.Thereareteamsouttherethatactuallyhavelotsoftimetodoarealworldjob,andturna500line

http://yosefk.com/c++fqa/fqa.html 71/112
2/26/2015 C++ Frequently Questioned Answers
simple,working,fastprototypeprograminto30Klineincomprehensible,broken,slow"product"becausetheythinkthatthey
aredealingwithanimportanttask,sonowisthetimetowritepilesofwrappercode.

[19.9]Okay,soexactlyhowshouldIdecidewhethertobuilda"protected
interface"?
FAQ:Therearemanyusefulguidelines,forexample:growup,don'tdothingsthatcanjeopardizeyourschedules,andonly
investtimeinthethingswhichwillultimatelypayoff.

FQA:Ifyoufindthisadviceuseful,here'smore:don'tbeanidiot,belucky,andavoidpushingsharpobjectsintoyourbody.

It'sratherannoyingthattheC++FAQdarestotellpeopletobe"practical".Whydon'tyouaddathirdusefulbuiltintypeto
yourlanguage(wealreadyhaveintegersandfloats),say,astringoradictionary,andthentalkaboutthedifferencebetween
theoryandtherealworld?

Inheritancevirtualfunctions
ThispageisaboutvirtualfunctionsarareexampleofaC++featurewhichisneitherapartofCnorcompletelyself
defeating.

[20.1]Whatisa"virtualmemberfunction"?
[20.2]HowcanC++achievedynamicbindingyetalsostatictyping?
[20.3]What'sthedifferencebetweenhowvirtualandnonvirtualmemberfunctionsarecalled?
[20.4]WhathappensinthehardwarewhenIcallavirtualfunction?Howmanylayersofindirectionarethere?How
muchoverheadisthere?
[20.5]Howcanamemberfunctioninmyderivedclasscallthesamefunctionfromitsbaseclass?
[20.6]Ihaveaheterogeneouslistofobjects,andmycodeneedstodoclassspecificthingstotheobjects.Seemslike
thisoughttousedynamicbindingbutIcan'tfigureitout.WhatshouldIdo?
[20.7]Whenshouldmydestructorbevirtual?
[20.8]Whatisa"virtualconstructor"?

[20.1]Whatisa"virtualmemberfunction"?
FAQ:ThemostimportantthingaboutC++ifyoulookfromanOOperspective.

Withvirtualfunctions,derivedclassescanprovidenewimplementationsoffunctionsfromtheirbaseclasses.When
someonecallsavirtualfunctionofanobjectofthederivedclass,thisnewimplementationiscalled,evenifthecalleruses
apointertothebaseclass,anddoesn'tevenknowabouttheparticularderivedclass.

Thederivedclasscancompletely"override"theimplementationor"augment"it(byexplicitlycallingthebaseclass
implementationinadditiontothenewthingsitdoes).

FQA:IfyouarenewtoOO,usingC++asyourfirstexampleisnotaverygoodidea.Ifyoustillwanttostartlearningabout
OOhere,andyoufeelyoudidn'treallyunderstandtheverygenericstatementsabove,here'sanexampleattemptingto
showwhyallthisisactuallyuseful.Note:thisFQAisunlikelytobethebestOOtutorialontheweb.

Supposeyouhaveaprogramwhichplaysmoviesindifferentformats.Nomatterwhattheformatis,youwanttohavethe
sameinterface(awindowwithamenu),options(resizethewindow,controlthecolorbalance...),etc.Now,youcandefinea
classMoviewithvirtualfunctionslikenextFrame(&pixels,&width,&height).Eachformatisimplementedinaderivedclass
likeMPEGMovie,DivXMovie...Thecodeimplementingtheinterface,theoptions,etc.canthenworkwithMovieobjects,calling
therightnextFramefunctionwithouthavingstufflikeif(format==MPEG) { MPEG_nextFrame(...); } else if ...alloverthe
place.Theformatindependentcodeiseasiertoread,andmucheasiertochangewhenyouwanttoaddanewformat,in
factaseasyasitgets:youdon'thavetochangeanything.

Ifthislastsentencemadeyoulaugh,you'veprobablyseenhowrepresentationspecificasupposedly"generic"interface
turnedouttobeoncesomeoneactuallytriedtocreateasecondorathirdimplementation.Youcanlaughsilently,oryoucan
doitoutloud,tosoonfindyourselfsurroundedbynewbiesclutteringtheircodewithidioticconditions("thewizardsaidthat
nothingisreallygenericanyway").Solet'sforgetthewhole"pseudogeneric"issueforthemomentandfocusontheC++
flavorofpolymorphisminstead(tothosewhodidn'tknow:hordesoflanguageshavesomethinglikevirtual,andnormally
it'ssomethingbetter).

virtualfunctionshavetheirproblems.Thekeyworditselfisobscure,the=0;notationisevenmoreso,youcan'tlookata
derivedclassandsaywhichfunctionsarevirtual(thekeywordisoptional),andoverloadingmakesitevenhardertosee
http://yosefk.com/c++fqa/fqa.html 72/112
2/26/2015 C++ Frequently Questioned Answers

whenafunctionactuallyoverridesabaseclassimplementation(forgetaconstintheprototypeanditbecomesanunrelated
virtualfunctionwiththesamename).SeasonedOOprosmightpointoutthelackofmultimethodsandinvariants/contracts
checking,andhaveothercomplaintsthatInolongerremember,butwhichseemedvalidwhenIdid.Oh,andthere'sthe
poorRTTIandthenonexistingreflection.Itgoesonandon.

However,comparedtootherC++features,virtualfunctionsareexcellent.Theymakeaveryusefulthingeasy.Yougetto
typelesscomparedtoC,whereyouwouldhavetocreatea"vtable"structandthendothingslikepThis->vptr-
>f((Base*)pThis, args)insteadoftheC++p->f(args).AndthisbrevitydoesnotcomeatthepriceC++makesyoutopay
sopromptlythere'snocompiletimeoverhead.

Therefore,ifyouareapractitionerusingC++,ignoringthe"performanceoriented"brainwashing("arraysofpointersto
objectswithvirtualmethodsaresooooslow,arraysofstructswithinlinefunctionsaresoooofast")andusingthesingleC++
featurethathasapotentialofdoinglessharmthangoodisveryfrequentlytherightthingtodo.OfcoursenotusingC++for
codecharacterizedbycomplicatedstructureanddynamicbehaviorisanevenbetteridea.

[20.2]HowcanC++achievedynamicbindingyetalsostatictyping?
FAQ:Statictypingmeansthatwhenafunction(virtualorother)iscalled,thecompilerchecksthatthefunctioncallisvalid
accordingtothestaticallydefinedinterfaces.

Dynamicbindingmeansthatthecodegeneratedfromthestaticallycheckedfunctioncallsmayactuallycallmanydifferent
implementations,andfiguresouttheonetocallatruntime.

BasicallyC++allowsmanythingstobedoneuponavirtualfunctioncall,aslongasthesethingsfollowaspecifiedprotocol
thebaseclassdefinition.

FQA:It'simportanttokeepinmindthatthecompilercanonlycheckwhetheranimplementationfollowsaprotocoltoa
certainextent.Itisprettyeasytocreateaderivedclasswhichlookslegitimate(ithasaninsertandafindmethodas
specifiedinthebaseclass),butinfactitisnot(becauseinsertdoesn'treallyinsertanythingtoanywhere,andfinddoesn't
findanything).Thiswillbreakthecodeusingthederivedclassviapointerstobaseclassobjects(thiscodewillinsert
somethingandthenwon'tfinditandwillcrash).That'swhytheFAQhasawholesectiononproperinheritance.

The(natural)factthatyoucan'tfindallerrorswithstatictypingwouldn'tbethatbadifC++didn'tcrashashardasitdoes(for
instance,bydoingruntimeboundarychecking),and/orwouldsupportdynamiccontractchecking,and/orhadacleartype
systemthatwouldmakespecifyinginterfaceslessofapain(currentlyyouhaveazilliontroublesrangingfromnobuiltin
stringtypetotheendlesskindsoftyperelationshipsandconversionrules).

Dynamicbindingisacriticalfeaturetobuildextensiblesoftware,andallgeneralpurposeprogramminglanguageshave
someformofit(inparticular,Chasfunctionpointers).Unlikedynamicbinding,statictypingisnotstrictlynecessary,butit
hasmanybenefits(thecodemaybeeasierforpeopletoreadandforcompilerstovalidateandoptimizeduetothe
informationspecifiedinthetypes)aswellasmanydrawbacks(somethingsmaybehardtomodelinastatictypesystem,
frequentlythere'smorecodetoreadandwrite,etc.).Atthelanguagelevel,C++doesn'tsupportdynamictyping(asopposed
to"binding")atall,anditsstatictypesystemisoneoftheworst.

SomeC++programmersthink(orfeel)thattheircompilerdoesanincredibleserviceoffindingvirtuallyalloftheirbugs.
Theirhiddenmotivesincludetheneedtorationalizetheamazinglylongbuildcycles,andtoavoidwritingtestprograms
(moreverbose,ugly,boringC++codewhowantstodothat?!).You'lldoyourselfafavorbynotcatchingtheirthinking
habits.

[20.3]What'sthedifferencebetweenhowvirtualandnonvirtualmember
functionsarecalled?
FAQ:nonvirtualfunctionsareresolvedatcompiletime.virtualfunctionsareresolvedatruntime.

Thecompilermustgeneratesomecodetodotheruntimeresolution.Thiscodemustbeabletolookatanobjectandfind
theversionofthefunctiondefinedbytheclassoftheobject.Thisisusuallydonebycreatingatableofvirtualfunctionsfor
eachclasshavingthem(the"vtable").Allobjectsoftheclasshaveanimplicitlygeneratedmemberpointer(the"vptr"),
initializedtopointtotheclassvtablebyallconstructors.

Toimplementavirtualfunctioncall,thecompilergeneratescodesimilartothatitwouldproducefromtheCexpression(*p-
>vptr->func_ptr).Thatis,itdereferencestheobjectpointertofetchthevptr,thenfetchesthefunctionpointerfromafixed
offset,thencallsthefunctionthroughthepointer.

Theexactcostdependsoncomplicatedstufflikepagefaults,multipleinheritance,etc.

http://yosefk.com/c++fqa/fqa.html 73/112
2/26/2015 C++ Frequently Questioned Answers
FQA:Inpractice,thecostisalmostneverabigdealunlessyoucallvirtualfunctionsinyour"innermostloops"(thecode
processingthemostdata).I'mnotsayingthecostshouldbeignoredagoodlookinggenericdesigncenteredaroundvirtual
callsininnermostloopsisinvalidformostpracticalpurposes.I'mjustsayingthatyoudon'thavetothinkaboutthingslike
pagefaultstofigureoutifyoucanaffordvirtualinthispieceofcode.TheC++implementationofpolymorphismispretty
efficient.

Onekindofpriceyoupayforthisefficiencyistheinstabilityofyourinterfacesatthebinarylevel.Youcanaddnewderived
classestoyoursystemwithoutrecompilingoldderivedclasses.Butyoucan'taddavirtualfunctiontoabaseclasswithout
suchrecompilation.Thisrulesoutstraightforwardusageofvirtualfunctionsinmanysituations(ifyouthinkrecompilation
has"zerocost",trytogetthevendorsofyourdesktopsoftwaretorecompileitsoitrunsonadifferentprocessor
architecture).

ManyOOlanguagesavoidtheseproblems.Onewaytodoitisjustintimecompilationinsteadofgeneratingcodefetching
thefunctionpointerfromafixedvtableoffset,waituntilyouseealltheupdatedbaseclassdefinitionsatprogramloadtime
andthengeneratetheoffsets.Anotheroptionistouselessefficient,butmoreflexiblelookupmechanisms,suchashash
tablesthisistypicallycoupledwiththelackofstatictyping,whichhasmanybenefitsanddrawbacks.Bothtechniques
avoidahugeamountofreallifeproblemswithbinaryinterfacestability.

Ifyoucan'tswitchtoadifferentOOlanguagewithbetterOOsupport(thinkaboutittheinterfacestabilityisjustoneaspect,
you'llprobablyalsogetgarbagecollection,fasterbuildcycles,andatonofotherusefulthings),youcanworkaroundthese
problemsinmanyuglyways.Forexample,youcanhaveasinglevirtualfunctiongettingastringoravoid*tellingitwhat
todo(afamousexampleofachievingbinarylevelstabilitythiswayistheioctlsystemcallofUnixlikesystems).Another
approachistoaddnewclassesforthenewfunctions,andhavethederivedclassesimplementmanydifferentabstractbase
classes(theCOMQueryInterfacefunctionworksthisway).Thesethingsarenotpretty,buttheyarebetterthannothing,
whichiswhatvirtualfunctionsdeliverwhenyouneedstableinterfaces.

Don'tbeashamedofyourselfifyoureachtheconclusionthatyouhavetodothis.If"performanceaware"peoplesqueak
somethingaboutit,trytogetthembusywithsomethingelse,likeimplementingstd::valarraytoactuallycompiletofast
codeusingSIMDinstructionsofthehostprocessor,withoutcreatingtemporarymemoryobjects.Thisshouldgiveyoua
coupleofcenturieslongbreak.

[20.4]WhathappensinthehardwarewhenIcallavirtualfunction?How
manylayersofindirectionarethere?Howmuchoverheadisthere?
FAQ:There'salotofcodelistingsexplainingthepreviousanswerindetail.

FQA:By"hardware",youprobablymeant"binarylevelsoftware"foreachpopularbinaryinstructionencodingtherearelots
ofvariantsofprocessorsimplementingit,andtheprocessorsareintegratedintomanydifferentsystemswithallkindsof
memoryarchitectures.Evenwhenyouwriteassemblycode,youcan'ttellexactlyhowit'sgoingtobeexecuted,soofcourse
youcan'twithahigherlevellanguagewhichcanbecompiledtoassemblyinmanydifferentways.

Astolevelsofindirectionstypicallytherearetwo,onetofetchthevptrfromtheobjectandanotheronetofetchthefunction
fromthevtable.Oneotherapproachcouldbetosavealevelofindirectionbykeepingthevtableinsidetheobject"byvalue"
insteadof"bypointer"butthatmakestheobjectslarger.

Astheproponentsofvirtualmethodscorrectlypointout,someoverheadisinevitableinthesituationswhereyouusea
virtualfunction,becauseyoudon'tknowwhatfunctiontocallatcompiletime.Ofcoursedifferentwaystoimplementthe
decisionmakingcanhaveslightlydifferentperformancecharacteristicsonagivenplatform.Ifyoucareaboutsuchtiny
differencesthough,youprobablyhavetofixitatahigherlevel(suchasmovingthedecisionoutsideoftheinnermostloopat
thecostofpossiblyreplicatingsomeofthecommoncode).Fiddlingwiththelowlevelimplementingthedecisionislotsof
boringwork(rewrite,measure,rewrite,measure...)withlittlegain.

[20.5]Howcanamemberfunctioninmyderivedclasscallthesamefunction
fromitsbaseclass?
FAQ:Forsomeareason,aprettylowleveldiscussionfollows.Namemangling,"callbyname"vs"callbyslotnumber",
codelistingswithdoubleunderscores...

FQA:Inaclass Derived,inafunctionDerived::f(),youcantypeBase::f();tocallthefimplementationfromyourbase
classBase.Thecompilerwillignoretheactualtypeofyourobject(atthelowlevelvtableandallthat),andcallBase::fjust
thewaynonvirtualfunctionsarenormallycalled.

IthinkyoucandothatineveryOOlanguage.It'sprettynatural.

http://yosefk.com/c++fqa/fqa.html 74/112
2/26/2015 C++ Frequently Questioned Answers

[20.6]Ihaveaheterogeneouslistofobjects,andmycodeneedstodoclass
specificthingstotheobjects.Seemslikethisoughttousedynamicbinding
butIcan'tfigureitout.WhatshouldIdo?
FAQ:"It'ssurprisinglyeasy",saystheFAQ.Thisstatementisfollowedbyasurprisinglylonganswer.

FQA:Idon'tknowhow"surprising"thisisthat'sthewhole(theoneandtheonly)pointofpolymorphism:todoclass
specificthingstoobjects,withoutthinkinghowheterogeneoustheyare.

Forthistowork,havetheclassesofthoseobjectsderivefromacommonbaseclass(notextremely"easy"unlessyou
plannedahead...).Thenyoucanrunovertheelementsofstd::list<Base*>,andcallthevirtualmethodswhichdotheclass
specificthingswithoutthinkingabouthowmanydifferentclassestheobjectsactuallybelongto,etc.Forexample:
for(std::list<Shape*>::const_iterator p=shapes.begin(), e=shapes.end(); p!=e; ++p) {
(*p)->draw(window);
}

Offtopic:theSTLwayofsayingforeach p in shapesisprettyugly,isn'tit?

[20.7]Whenshouldmydestructorbevirtual?
FAQ:Theruleofthumbiswhenyouhaveavirtualfunction.Strictlyspeaking,youneeditwhenyouwantsomeonetobe
abletoderiveclassesfromyourclass,createobjectswithnew,anddeletethemviapointerstoabaseclass.

FQA:Thesituationswhentheruleofthumbisnotgoodenoughwerenotreportedonourplanet.Usethisruleofthumb,if
onlytosuppresscompilerwarnings.ToobadtheC++compilerdoesn'tusetherulesilentlyitselfitcouldsimplymakethe
destructorvirtualinthesecases.

[20.8]Whatisa"virtualconstructor"?
FAQ:It'sanidiomallowingyoutohaveapointertoabaseclassanduseittocreateobjectsoftherightderivedclass.You
canimplementitbyprovidingvirtualfunctionslikethese:
virtual Base* create() const;
virtual Base* copy() const;

Youimplementthemlikethis:
Derived* Derived::create() const { return new Derived; }
Derived* Derived::copy() const { return new Derived(*this); }

NotethatwereturnDerived*,notBase*it'scalled"CovariantReturnTypes".Somecompilershaveit,somedon't.

FQA:Otherlanguageshavebuiltinsupportforthesethings.Thisisinterestingbecauseoftheotherthingstheymake
possible,likeserialization(withoutwritingspecialcodeforeachclass).Roughly,thisiscalled"reflection":youcanfindall
methodsofaclassatruntime,includingthosethatarenotnormallycalledasvirtual,suchasconstructors(whichcan'tbe
virtualyouhavetocreateanobjectbeforeyoucandispatchfunctioncallsbasedonitstype).Anotheroptionisto
(recursively)getthelistofmembersofaclassandcreate/copythem.It'shardtoimaginehowusefulthisisifmostofyour
programmingexperiencecomesfromworkingwithC++.

Covariantreturntypesareanicejoke(foranadmittedlynarrowaudiencethough).C++letsyoutightenthespecificationof
returnvalueswhichisperfectlylegitimate:ourbaseclasssaidweshouldreturnaBase*,andwesurelyimplementthe
contractifwealwaysreturnaDerived*,whichisinparticularaBase*.ButC++doesn'tletyouloosenthespecificationof
arguments,whichcanbeshowntobelegitimateforsymmetricalreasons.

Why?BecauseC++hasoverloading,sowhenyoudeclareavirtualfunctionwhichlooksjustlikeafunctionfromyourbase
class,buthasanykindofchangestoargumenttypes,C++thinksyoucreateanewunrelatedvirtualfunctionratherthan
overridetheonefromthebaseclass.SinceC++hasnooverloadingbasedonthefunctionreturntype,there'sno
symmetricalproblem.

C++haslotsofkindsofstatictyping,butlittleconsistencybetweenthem.Tobefair,otherlanguageshavesimilar
interactionsbetweenoverloadinganddynamicbinding,andsomeprobablycopiedthemfromC++.However,other
languagesrarelyencouragedesignwhichdependsontheavailabilityofoverloadingtowork(likeSTL),and/orisbasedon
themicroscopicdetailsofoverloadresolutionmechanisms(likesomeoftheboostlibraries).

http://yosefk.com/c++fqa/fqa.html 75/112
2/26/2015 C++ Frequently Questioned Answers

Inheritanceproperinheritanceandsubstitutability
Thissectionisaboutusinginheritancesuchthatthecodereallyworks,notjustcompiles.Unlikemost"OO"relatedsections
intheFAQ,muchofthematerialisapplicabletodecentOOsystemsandnotonlytoC++.

[21.1]ShouldIhidememberfunctionsthatwerepublicinmybaseclass?
[21.2]ConvertingDerived* -> Base*worksOKwhydoesn'tDerived** -> Base**work?
[21.3]IsaparkinglotofCarakindofparkinglotofVehicle?
[21.4]IsanarrayofDerivedakindofarrayofBase?
[21.5]DoesarrayofDerivedisnotakindofarrayofBasemeanarraysarebad?
[21.6]IsaCircleakindofanEllipse?
[21.7]Arethereotheroptionstothe"Circleis/isnotkindofEllipse"dilemma?
[21.8]ButIhaveaPh.D.inMathematics,andI'msureaCircleisakindofanEllipse!DoesthismeanMarshallClineis
stupid?OrthatC++isstupid?OrthatOOisstupid?
[21.9]PerhapsEllipseshouldinheritfromCirclethen?
[21.10]Butmyproblemdoesn'thaveanythingtodowithcirclesandellipses,sowhatgoodisthatsillyexampletome?
[21.11]Howcould"itdepend"??!?Aren'ttermslike"Circle"and"Ellipse"definedmathematically?
[21.12]IfSortedListhasexactlythesamepublicinterfaceasList,isSortedListakindofList?

[21.1]ShouldIhidememberfunctionsthatwerepublicinmybaseclass?
FAQ:No,no,don'teventhinkaboutit,don'tdothat,no.Yourdesireisprobablytheresultof"muddythinking".

FQA:Withallduerespect,itisyourpreciousprogramminglanguagethatprobablyistheresultof"muddythinking".The
questiontalksaboutoverridingbaseclassfunctionsintheprivatesectionofyourderivedclass.Thisistriviallyandreliably
detectableatcompiletime.Ifyougetsoexcitedabouthowwrongitis,whydoesitcompile?

Answer:inC++,randomthingscompileandotherrandomthingsdon't.Thelanguagedefinitionissloppy.What'sthat?You
thinkthecompilerwritersmadetheirownjobeasybymakingyourshard?No,C++isprobablythehardestlanguageto
compileamongthosepopulartoday.C++ispointlesslysloppy.

ThereasontheFAQgetssoexcitedwillbecomeclearinthenextanswers.Basically,whenyourderivedclassoverridesa
functionasprivate,youviolatethesubstitutabilityprinciple:itisnolongertruethatanobjectofaderivedclassfully
supportstheinterfaceofthebaseclass.However,technicallythefunctionsfromthebaseclassarestillaccessible,because
youcancastapointertoaderivedclassobjecttothebaseclassandcallthefunctionthroughthevtable(prettymuddy,isn't
it?).

Peopledefineoverriddenvirtualfunctionsasprivatetoconveythemessagethatobjectsofthederivedclassshouldnever
beuseddirectly,andthepurposeoftheclassistointeractwithaframeworkwhichworkswithobjectsthroughbaseclass
pointers.WhiletheFAQgetsoverlyhystericalaboutthispractice,thepolarityofitsanswer("no")isprobablyright.

[21.2]ConvertingDerived* -> Base*worksOKwhydoesn'tDerived** ->


Base**work?

FAQ:Becauseitshouldn't.Let'spretenditdoesworkandseewhathappens.

SupposeyouhaveaDog* d.Youpassittoafunctionvoid f(Pet** p)withf(&d)whichshouldbeOK,sinceDogisderived


fromPet.Thefunctiondoesthis:*p = new Cat;perfectlylegitimate,sinceCatisderivedfromPet,too.Butnowwehavea
Dog*pointingtoaCatobject.Sod->bark()willcrashtheprogram,ormisbehavemoreseverely,sinceaCatmayhavea
virtualfunctionscratchFurnitureatthatslotofthevtable.

Actually,theFAQusesascarierexample,whichlaunchesnuclearmissilesastheresultofthemistake.IMHO,nothingcan
beatthefollowingclassicinthisdepartment:
if(status = UNDER_ATTACK) {
launch_nuclear_missiles();
}

BestIndustryPractice:usepeerreviewstoincreasethequalityofyournuclearmissileslaunchingcode.

FQA:Yep,levelsofindirectionandstatictypinginteractinnonobviousways.Thisisanotherincarnationoftheproblem
makingitimpossibletocastT**toconst T**.Basically,aT*isalwaysaS*doesn'tmeanaT**isalwaysaS**.

Theproblemisthattherearemanycaseswhereyouknowthatyouaredoingsomethinglegitimate,butthecompiler

http://yosefk.com/c++fqa/fqa.html 76/112
2/26/2015 C++ Frequently Questioned Answers
doesn't.Forexample,youknowthatitwasyouwhofilledthisvectorofPetswithabunchofDogs.Youcouldn'tuseavector
ofDogsbecauseyouwantedtopassittoafunctionworkingwithavectorofPets.Andaswe'vejustseen,thecompiler
wouldn'tletyoupassavectorofDogstoafunctionexpectingavectorofPets,andforagoodreason.Soyouendedupwith
avectorofPetsfilledwithDogs.AndnowyouwanttofetchaDogfromthevectorbuttheelementsaretypedasPets,so
youhavetouseacast.Itwouldn'tbethatbadifthesecaseswouldn'tcausemanypeopletodevelopahabitofaggressive
castingtohavethecompilershutup,and/orC++wouldcatchillegalcastoperationsatruntime.

Moral:statictyping(havingthecompilervalidatethecodeaccordingtoasetofrulesspecifyingpropertiesoftypesandtheir
relationships)ishard.Astatictypesystemwillgetinyourway.Anditonlypartiallycompensatesyouby"validatingthe
interfaces",becauseonlysomeofinterfacespecificationcanbemodeledstatically,aswe'llseebelow.Inparticular,
considerourexamplewhereyouhadtostuffyourDogobjectsintoavectorofPetpointers,allbecausethecompilerinsisted
ontheloosertyping.Nowthecompilerwon'tpreventsomeoneelsefromaddingaCatpointertothatvector,andthenyour
codefetchingaPet*fromthevectorandcastingittoaDog*willmisbehave.

I'mnotsayingthatstatictypingis"bad",butifyouthinkthatdynamictypingisbad,youareveryluckyyou'rejustonestep
awayfromaquitenoticeableincreaseinyourproductivity.Pickadynamicallytypedlanguageandgiveitatry.

[21.3]IsaparkinglotofCarakindofparkinglotofVehicle?
FAQ:No,becauseaPlaneisonekindofVehicle,andyoudon'twantsomeonetoparkitatacars'parkinglot.

FQA:InEnglish,apparentlytheanswerisyes.InOO,theanswerisno.Innaturallanguage,there'snostrictdefinitionof
"kindof"(oranythingelse,forthatmatter).OOsystemsareformal,andtheyhaveaprecisedefinitionfor"kindof":Bisa
kindofAifyoucandotoaBobjectwhateveryoucandotoA,anditwillworkcorrectly(notjustcompile).

Programminglanguagesarenotnaturallanguages.Inparticular,thegoodprogramminglanguagesdon'ttrytolook"natural"
whensuchattemptsmakeithardtounderstandtheformal,preciseanddumbstuffthemachineactuallydoes.Ifyouever
wonderedwhatonEarththeC++expressiona->bdoes(whenaisanobjectofasmartpointertemplateclasswith7
parameters),youknowwhatImean.

[21.4]IsanarrayofDerivedakindofarrayofBase?
FAQ:No.Thinkofthearrayasanimplementationofaparkinglot,andyou'llseethattheanswerfollowsfromtheprevious
FAQ.

FQA:Notethattheabilityofthecompilertofigureoutwhethersomethingisakindofsomethingelseislimited.Inparticular,
itseemstoworkbetterwithtypesrelatedbyinheritance(baseandderivedclasses)thanwithtypesrelatedbyqualifiers
(constandnonconst)orbythewaytheyareinstantiatedfromthesametemplates.Forexample,avector<T*>isapparently
akindofconst vector<const T*>,becausethere'snothingyoucandowithanallconstvectoryoucouldn'tdowithanall
nonconstvector.Butthecompilerdoesn'tknowthat.

Onewayaroundthisis"ducktyping"don'tbothertospecifytherelationshipsbetweenthetypes,justpassobjectsto
functions,whichwillworkiftheobjectcandowhatevertheyaskittodo,andraisearuntimeerrorotherwise."Ifitwalkslike
aduckthenitisaduck"andallthatyoudon'thavetodefineaDuckinterfaceallducksshouldfollow,justgetanobjectand
callmethodssuchaswalkLikeADuck.C++doesn'thaveducktypingbecauseitwouldrequirethecompilertorelyonnon
trivialandnotsolightweightruntimemechanisms,whichkindofgoesagainstthe"spirit"ofC++(notthattheruntime
mechanismsusedtoimplementexceptionsaretrivial,mindyou).

Onecouldclaimthatducktypingisincompatiblewiththe"spiritofC++"becauseitinvolvesruntimedispatching,butsodo
virtualfunctions,whicharemoreefficientbutlessflexibleandmuchmorelikelytotriggerrecompilationsabigdealin
manysituations.Oronecouldclaimthatducktypingisnot"theC++way"becauseitleavesoutthespecificationof
interfaces,butsodotemplates,whichprovide"staticducktyping"toobadtheyaresuchapileoftoxicwastethatthescope
ofthisdiscussionistoonarrowtoevenbrieflydescribewhy.Oronecouldclaimthatwithducktyping,youcanfailatrun
timebecausesomeoneprovidedanobjectofthewrongtypebutnothingpreventssomeonefromsimplypassinganull
pointertoaC++functionthatcan'thandlethatandhaveitcrashmuchharderthananycodeinasafedynamiclanguage
everwill.

ThetruereasonmakingducktypingincompatiblewithTheC++Wayisthe95%IsNothingAxiom.Itgoeslikethis:"if
somethingisonlyusefulfor95%ofthecases,anditdoesn'tmapalmostdirectlytoC,it'snotworthaddingtoC".Other
examplesoftheapplicationofthisaxiomtothedesignofC++isthelackofgarbagecollection,which"only"handles
memory(>95%ofall"resources"),and"only"innonrealtimeapplications(>95%ofallapplicationcode).

Theconsequencesofthisaxiomwouldn'tbethatbadifthefeaturesC++didaddtoCwereanygood.

http://yosefk.com/c++fqa/fqa.html 77/112
2/26/2015 C++ Frequently Questioned Answers

[21.5]DoesarrayofDerivedisnotakindofarrayofBasemeanarraysare
bad?
FAQ:Yes,arraysareevil.Normallyyoushouldusestd::vectorinsteadofarrays.ButifyouareanenlightenedOO
specialistandsoiseveryonelikelytomaintainyourcode,andyoufullyunderstandtheinteractionof"kindof"andarrays,
youmayusethem.

FQA:Huh?Arraysandvectorsaresynonymsinthecontextofthe"kindof"issue.Whatdoesthecultadvocatingthe
replacementofCfeatures,whichhavetheirproblems,withnewshinyC++featureshavingmuchworseproblemshavetodo
withproperinheritance?

What'sthat?Castingarraysiseasierthancastingvectors?Trythis:(vector<T>*)&vec_of_something_else_than_T.Seriously,
thisisoneweirdquestionwithastrangeanswerwehavehere.

[21.6]IsaCircleakindofanEllipse?
FAQ:Sometimesitis,mostfrequentlyitisn't.Forexample,ifanEllipseletsyouchangethesizeinawaymakingit
asymmetrical,it'snotaCircle.

ThepointisthatifyouderiveaCirclefromanEllipseandthensomeonetriestouseanEllipse*whichreallypointstoa
Circleobject,there'snowaytomakeitworkgracefully.Eitherthecallingcodewillgetanerrorinsomeform,eventhoughit
doessomethingwhichshouldbepossibletodowithanEllipse,ortheCircleobjectwillobeytothecallerandbecomean
invalidcircle,breakingsomeotherlegitimatepieceofcodewhichdoesexpectittobeavalidcircle.

FQA:Thisisjustliketheparkinglotexampleinthesensethat"kindof"inEnglishmeansmanydifferentthings,someof
whichareincompatiblewiththeprecisedefinitionof"kindof"usedinOO.Theimportantpointisthattheinterfacesare
protocolsandimplementationsmustfollowthem.

Somepeoplethinkaboutinheritancemerelyasanotherformof"binding"havingthecompilercallafunctionusingnew
syntax.Fromthispointofview,everythingislegitimateaslongastheprogramcompilesanddoeswhatevertheenduser
expects.Butthiswayinheritanceonlymakesprogrammingharder(anotherkindofsyntaxtodecipher).Themorerestrictive
"interfacesasaprotocol"approachcanmakeprogrammingeasierbecausewhenyouimplementabunchofprotocols
correctly,youcanextendaprogramwithouttweakingitscode(forexample,addamovieformattoamediaplayer).Butthis
onlyworksifyoureallyfollowtheprotocol.Ifyousortofdoit("aCircleisakindofEllipse,well,almostjustdon'tcallthis
function"),themediaplayerwillcrash.

TherearenumerousfamiliesofexampleswherenaturallanguagesandOOtermsarenotaligned(whichdoesn'tmeanOO
isbaditmeansit'sformal,whichisgoodforcomputerprogramming).The"parkinglot"representsonefamily(collections)
Circle/Ellipserepresentanotherone(parametricrepresentations).Onefamilyof"positive"examples(whereinheritanceis
likelytobeproper)isrecordtypes(aCPlusPlusProgrammerhasallthefieldsofaProgrammer,plusacoupleofnew,
orthogonalmembers,suchasheadAgainstTheWallBangingFrequency).

[21.7]Arethereotheroptionstothe"Circleis/isnotkindofEllipse"
dilemma?
FAQ:Well,youneedtogetridofsomeofyouroriginalclaimstogetbacktoconsistency.EitherEllipsehasnosetSize
functionwhichcanmakeacircularEllipseobjectnoncircular,orthere'snoinheritancewhichmakesitpossibletocallsuch
afunctiononaCircleobject,oryoucanevenchoosetolivewiththefactthatsomeofyourCircleobjectswillbecomenon
circular(andhavethecodeworkingwithCircleobjectsdealwithit).

Tryingtokeepallclaimsandcoveruptheproblembydoing"somethingreasonable"(likecallingabortwhensetSizeis
calledwithaCircleobject,or"fixing"itsarguments)isnotgoingtosolvetheproblem,becauseultimatelyitbreaksthe
assumptionsbehindthecallingcode.

FQA:TheFAQanswerisapparentlycorrectandcomplete.Incidentally,thisisn'texclusivelyaboutC++,it'saboutOOin
general.

OnesolutionistohavesetSizereturnanewEllipseobject.Thisway,Circle::setSizewillreturnaCircleunlessthenew
sizeisasymmetrical,inwhichcaseitwillreturnanEllipse.Onepossiblebenefitisefficiencycircleshavelessparameters
thanellipses,soifyouhavelotsofoperationstodowithabunchofobjects,you'dratherhavealloftheobjectsthatcanbe
representedasCircleobjectsactuallyberepresentedthatway,notasredundantEllipseobjects.

Ifyou"rollyourownOO"(thatis,implementinheritanceyourselfinsteadofdirectlyrelyingonlanguagefeatures),youcan

http://yosefk.com/c++fqa/fqa.html 78/112
2/26/2015 C++ Frequently Questioned Answers
avoidthecreationofanewobjectandinsteaddynamicallychangeitstype.Forexample,setSizemaychangethevptrto
pointtoanEllipsevtablewhenthenewsizeisasymmetrical.ThiskindofthingisimplementedinthePOVRayraytracer,
writteninC.

Thefactthatyoucan'tdoitinaportablewaywithC++inheritanceprobablydoesn'tmeanthatC++inheritanceis
underpowered(surprise!)youneedthiskindofthingonceinalifetime,andyoumusthaveitverywellthoughtouttomake
itreallywork,andintheserarecasesyoucangoaheadandusefunctionpointersinsteadofinheritanceandimplementit.
Thereprobablyarepeoplethatwouldclassifythislimitationasasymptomofadeeperproblemhavingtoomuchlogicbuilt
intothecompilerandtoolittlewaystoimplementcompiletimelogicinusercodebutit'sdebatable.

[21.8]ButIhaveaPh.D.inMathematics,andI'msureaCircleisakindofan
Ellipse!DoesthismeanMarshallClineisstupid?OrthatC++isstupid?Or
thatOOisstupid?
FAQ:Itmeansadifferentthing:yourintuitioniswronginthesensethatitleadsyoutomakewrongdecisionsabout
inheritance.Therightwaytothinkabout"kindof"isthis:BisakindofAifyoucanalwayssubstituteaBforanA.

FQA:Ilikehowthisquestionisformulated.Showsspirit.Ingeneral,theFAQcanbequiteentertainingifyou'reintothatsort
ofthing.IfIcouldlegitimatelyquotetheanswersinsteadofsummarizingthem,I'dsurewould.

Whichisallniceanddandy,butdidyounoticethedisturbingclaim"yourintuitioniswrong"?InsteadofadmittingthatOOis
notanaturallanguage,anditdoesn'thavetomapdirectlytoanaturallanguage,theFAQactivelytriestopersuadeyouto
changethewayyouusenaturallanguagewordstomakeyourthinkingOOcompatible.Next,they'llshippatchesyoushould
applytoyourDNA,andastickersaying"DesignedforC++Programming"foryourskull.

Ithinkthispointisworthdiscussionbecauseit'srepresentativeofthewholenotionof"good"intheC++world.C++triesto
maketheprogramlooknatural.Seeweaddthingswiththeplussign,anderrorsarehandledtransparently,andresources
aremanagedautomaticallythat'soneveryhighlevellanguage,andit'sefficient,too!Butmakeasingleerrorinyour
programandfindingitbecomesannightmare.Whatisreallybeingcalledbythisa+bexpression?Whatreallyhappens
uponerror?Andthisobjectwedeallocateherehowdoweknownobodyiskeepingapointertoit?Becauseallourpointers
are"smart"?Butlookhereweusealibraryusingbarepointers,andhere'soneusingdifferentsmartpointerclasses.What
isreallygoingonhere?

ThebasicruleC++breaksisthis:don'tmakepromisesyoucan'tkeep.Don'tsaythatinheritanceisequivalenttotheway
peoplethinkabout"kindof"introduceitfromthebeginningintermsofsubstitutability.Don'tpretendyoumanageresources
"automatically"wheninfactit'stheresponsibilityofeveryonetofollownontrivialprotocolsforthistowork,andasingleerror
isfatalmakeitvisiblewhereresourcesareacquiredandreleased.Oryoucanreallymanagethemautomaticallywith
garbagecollectionorreferencecountingorotherwise.Butifyourefusetodoit,whichmaybeperfectlylegitimateattimes,
admitit.Changingyourtermsismoreproductivethanwaitingforeveryonetochangetheirs.

OfcoursetheCircle/Ellipseproblemisnotanexampleof"makingpromisesthatcan'tbekept".It'stheFAQ'sclaimsabout
OO"capturingthewaywethink"thataresuchanexample.

[21.9]PerhapsEllipseshouldinheritfromCirclethen?
FAQ:Probablynot.Forexample,whatwouldtheradius()accessordo,andhowwoulditbecompatiblewithanassumption
thatismostlikelyapartoftheCircleprotocolthatyoucanuseradius()tocomputethearea()?

FQA:Ithinkit'sveryeasytoseewithaslightlydifferent,butarelatedexample.Whatismorestupid:toclaimthatatriangle
isarectanglewithtwoidenticalvertices,orthatarectangleisatrianglewith4vertices?Itprobablysoundsequallystupidto
mostpeople.

ThemajorreasonmakingpeoplewhothemselveswouldthinktheseclaimsarestupidtogoaheadandderiveTrianglefrom
Rectangleorviceversaisthattheydon'tthinktheyareinfactmakingsuchclaimsbyimplementingsuchinheritance.

Theideaisthis:inheritanceisnotjustyetanotherkindofsyntax.Itspurposeisnottosaveacoupleoflinesofcodeinthe
derivedclass(whichyoumayaccomplishbyderivingTrianglefromRectangle).Andthecompilercan'tcheckthatyour
inheritanceiscorrect(thisisreallyhardforC++aficionadostoaccept:thecompilercan'tchecksomething!).Inheritanceis
aboutwritingcodethatfollowsaprotocol,makingitpossibletocallthiscodefromanyfunctionwrittentoworkwithobjects
thatfollowthatprotocol,andthusreusingthecallingcode(possiblyalotofsuchcodemuchmorethanthecoupleoflines
yousavedinthederivedclass).

Andifyourinheritancedoesnotguaranteesubstitutability,thenthecompilerwon'tbeabletocatchyourerror(it'stype
checkingassumesthatyouprovidesubstitutabilitythat'swhyitletsyouusepointerstoderivedclassobjectsincontexts
http://yosefk.com/c++fqa/fqa.html 79/112
2/26/2015 C++ Frequently Questioned Answers
expectingbaseclassobjectpointers).Andyou'llconfusemostpeople(frequentlyincludingyourself),whoalsoexpect
substitutability,especiallysincethecompileragreesbylettingthempassanEllipsewhereaCircleisrequired.Andifyou
reallydon'tneedsubstitutability,youdon'treallyneed(public)inheritance,either.

[21.10]Butmyproblemdoesn'thaveanythingtodowithcirclesandellipses,
sowhatgoodisthatsillyexampletome?
FAQ:Butyousee,allexamplesofimproperinheritancearebasicallyequivalenttotheCircle/Ellipsecase.Inheritanceis
badwhenabaseclassprovidesfunctionalitywhichaderivedclasscan'tprovide(intheEllipsecase,that'sasymmetrical
resizing).Theproblemwithinheritanceinsuchcasesisthatitcomeswithoutsubstitutability,breakingabasicassumption
sharedbyprogrammersusingtheclassesandthecompiler(whichautomaticallyallowstouseobjectsofderivedclasses
wherebaseclassobjectsareexpected).

FQA:Exactly.Peopleobsessedwithcompiletimeerrorchecking,repeat:thecompilerdoesthestatictypechecking(asin
"thisobjectisofclassDerivedOK,it'salegitimateparametertofunctionf(Base&)")basedonassumptionsitcannotcheck
("whoeverwroteDerivedmadeitsubstitutableforBase").Sayitagain:thecompilerdoesthestatictypecheckingbasedon
assumptionsitcannotcheck.Thecompilerdoesthestatictypecheckingbasedonassumptionsitcannotcheck.

Translation:thecorrectnessofaninterestingprogramcannotbecheckedatcompiletime.Allprogrammersaresupposedto
knowit,butsomekeepforgetting.Soisitultimatelybettertospendyourtimeontypesafety(thingslikemakingsurethat
nobodycancastvector<T>::iteratortotheunderlyingT*)orwritingtestscheckingthatyourcodebehavescorrectlyatrun
time?Youbethejudge.

[21.11]Howcould"itdepend"??!?Aren'ttermslike"Circle"and"Ellipse"
definedmathematically?
FAQ:Theyare,buttheclassesCircleandEllipsehaveadifferentdefinitiontheC++codedefiningtheclasses.Inyour
program,that'sthedefinitionofCircleandEllipse,andthat'swhatyouhavetolookattovalidateyourinheritance.Ifyou
keepthinkingaboutthemathematicalconnotations,let'sreplacetheclassnameswithFooandBarforthemomentthat'sall
thesameforthecompiler.

Nowthatwe'vedefinedthemeaningofCircleandEllipse,recallthat"inherits"means"issubstitutablefor"(not"isa"or"is
akindof",whicharenotprecisedefinitions).Withthesedefinitions,youcangettherightanswerusingthepreviousFAQs.

FQA:Exactlyyoucan'timplementthemathematicalnotionof"circle"inaprogramminglanguage,youcanonlyimplement
adefinition(possiblycalledCircle)orabunchofdefinitionswhichmodelsomeoftheaspectsofmathematicalcirclestoa
certainextent.Andwhenyoureasonaboutthecorrectnessofyourprogram,youhavetotalkaboutthesedefinitions,notthe
originalmathematicalnotion.

Lotsofsufferinginflictedbythemoretalentedprogrammersuponthemselvesoriginatesatthehopetoimplement"the
ultimatesomething"(forexample,"theultimatecircleclass"thatcapturesallaspectsofmathematicalcircles,soyou'dnever
havetodefineacircleclassagain).Theultimatesearchfor"theultimatesomething"inprogrammingisprobablythesearch
fortheultimateprogramminglanguage.Arguably,theC++languageisoneresultofthissearchittriestomeetahuge
amountofconflictingrequirements,thekeyonesbeing"readability,efficiencyandgenerality"ofC++code,aswellas
pseudocompatibilitywithC.Theresultisalargescalenightmare,andthemoralofthestoryissimple:designthebesttool
foreverything,andyou'llgetatoolgoodfornothing.

Onthebrightside,itisprobablypossibletodefineagoodCircleclassforyourprogramifyoutrytomakeitgoodforyour
programratherthanimplementthemathematicalnotion.AndthisiswhythemeaningofCircledependsonyourprogram.

[21.12]IfSortedListhasexactlythesamepublicinterfaceasList,is
SortedListakindofList?
FAQ:It'squiteunlikely.Forinstance,considerList::insert.Isitdefinedtoinserttheelementtotheendofthelist?Ifitis,
there'snogoodwaytoimplementitinSortedList,becausetheinsertiontotheendwillusuallymakethelistunsorted.

Thesubstitutabilityprincipleisaboutthespecifiedbehavior,notjustfunctionnamesandparametertypes.So"exactlythe
samepublicinterface"inthesyntacticsenseisnotenoughforproperinheritance,thespecifiedruntimebehaviormustbe
thesame.

FQA:Yep,compiletimetypecheckingcannotguaranteeproperinheritance,itcanonlyoperateundertheassumptionthat
youguaranteedit.That'swhysomelanguagescomewithcontractchecking:thebaseclassspecifiesthebehaviorusing

http://yosefk.com/c++fqa/fqa.html 80/112
2/26/2015 C++ Frequently Questioned Answers
inputandoutputconstraintscomputedatruntime,andyoucanhaveyourruntimeenvironmentautomaticallyevaluate
theseconstraintswhenmethodsofderivedclassesarecalled.

YoucansimulatethisbehaviorinC++bywritinglotsofcode.Namely,thebaseclasscanhaveapublicnonvirtualinsert
methodcallingaprotectedvirtualonInsertmethod.TheinsertwrappercanthencheckwhetheronInsertfollowsthe
protocolusingabunchofassertsbeforeandafterthecalltoonInsert.Since"alotofcode"ismostfrequentlybadbyitself
(becauseyouwastetimewritingitandthenwastemuchmoretimereadingittogetherwithotherpeople),thebenefitsare
notnecessarilyworththetrouble.Butruntimetests(standaloneorintegratedintoalargersystem)greatlyincreasethe
qualityofcode,andmakingruntimetestingsimpleandpainlesspaysoff,especiallycomparedtoworkspentoncompile
timeerrordetection.

Inheritanceabstractbaseclasses
C++abstractbaseclassesarenotbadatallbyC++standards.However,theyarequitepoorbyOOstandards.

[22.1]What'sthebigdealofseparatinginterfacefromimplementation?
[22.2]HowdoIseparateinterfacefromimplementationinC++(likeModula2)?
[22.3]WhatisanABC?
[22.4]Whatisa"purevirtual"memberfunction?
[22.5]Howdoyoudefineacopyconstructororassignmentoperatorforaclassthatcontainsapointertoa(abstract)
baseclass?

[22.1]What'sthebigdealofseparatinginterfacefromimplementation?
FAQ:Interfacesarethemostimportantthingpossessedbyacompany.Defininginterfacesishard,throwingtogetheran
implementationiseasy.Designinginterfacestakeslotsoftimeandisdonebypeoplewhoarepaidlotsofmoney.

Youwouldn'twantthesevaluableartifactsclobberedbyimplementationdetails,wouldyou?

FQA:Ifinterfaceisdecoupledfromimplementation,youcanhavemorethanoneimplementationofthesameinterface.This
way,codeusingtheinterfacecanworkwithallthoseimplementations.Forexample,thesamecodemaybeusedtorender
adocumenttoascreen,aprinterandafile.Whichisexcellent,andisaverywidelyacknowledgedandbasicfact.

It'samazingthattheFAQ'sanswerfailstomentionthis.TheFAQ'sclaimabouttherelativeimportanceofinterfacesand
implementationsisunbelievable,too.Here'saninterfaceforyou:
class SearchEngine
{
public:
// search the documents pointed by URLs in the inputURLs stream, search the query string
// in them and emit the URLs sorted by relevance to the outputURLs stream (at most maxResults URLs).
virtual void find(const string& query, istream& inputURLs, ostream& outputURLs, int maxResults) = 0;
};

Now,thattookabout1minute.It'syourturnto"throwtogetheranimplementation",whichshouldn'ttakemorethan30
secondsaccordingtheFAQ'sargument,shouldit?Go.

Ifyoudon'tlikethisexample("therearemorecomplicatedinterfacesinarealsearchengine"),thinkaboutmatchScore =
faceRecognition(suspectImage, testImage),fft(outputArray, inputArray, size),text = ocr(imageWithHandWriting),
render(screen,htmlPage),write(file,buffer,size)...Theideathat"implementationsaretrivial"canonlycomefrom
workingonextremelystupidapplicationsorexampleprogramsfortextbooks.

Ofcoursemanyinterfacesshouldbedecoupledfromimplementationsbutthat'sbecausetheyhideamuchmore
complicatedimplementation,and/orbecausetheyhavemorethanoneimplementation,and/orbecauseyouwanttochange
theimplementationwithoutaffectingtheclientcode.Surprisinglyenough,C++abstractclassesactuallyallowyoutoachieve
allthesethings.

Ofcoursetheydon'tfixmanyhardproblemswithC++there'snorealruntimetypeinformation,forexample.Andaddinga
functiontoanabstractclasschangesthebinaryinterface,whichisfrequentlyunacceptable.Butabstractclassesarebetter
thannothing,asopposedtothemanyC++featureswhichareinfactworsethannothing.

[22.2]HowdoIseparateinterfacefromimplementationinC++(likeModula
2)?
FAQ:Useanabstractbaseclass.
http://yosefk.com/c++fqa/fqa.html 81/112
2/26/2015 C++ Frequently Questioned Answers
FQA:Whatdoyoumean"likeModula2"?

Ifyouwanttobeabletoworkwithmanydifferentimplementationsselectedatruntime,abstractbaseclassisthewaytogo.
Alternatively,youcanrollyourown"abstractbaseclasses"byusingstructurescontainingfunctionpointers,emulating
"vtables".Thisresultsinextracode,butit'smoreportable(Cbinarycallingconventionsonagivenprocessorarchitecture
tendtobesharedbymoretoolsthanC++ones).

Ifyoudon'tneeddynamicimplementationselection,youcanuseaheaderfilewithforwarddeclarationsoftypes,andhave
thetypesdefinedintheimplementationfile(s).Thiswayyoucanchangetheimplementationdetailswithoutrecompilingthe
callingcode(whichyoucan'tdowithC++privatemembers).Inparticular,youcanbuildseveralversionsofyourprogram
withdifferentimplementationsofthisinterfacewithoutrecompilingtheentireprogram.

[22.3]WhatisanABC?
FAQ:Anabstractbaseclass.

Logically,itcorrespondstoanabstractconcept,suchasAnimal.Specificanimals,likeRat,SkunkandWeasel,correspondto
implementationclassesderivedfromAnimal.

Technically,aclasswithatleastonepurevirtualfunctionisabstract.Youcan'thaveobjectsofabstractclasses,youcan
onlycreateobjectsofclassesderivedfromthemthatimplementallthepurevirtualfunctions.

FQA:ABCisalsoanespeciallyannoyingabbreviation.

Hereareacoupleofthingsyoucan'tdowithaC++abstractbaseclass,andwhicharesupportedinotherOOlanguages.
Youcan'titerateoverthemethodsofanabstractbaseclass(neitheratcompiletimenoratruntime).Soyoucan'teasily
utilizethedecouplingbetweentheinterfaceandtheimplementationbyautomaticallygeneratingwrapperclassesthatlog
functioncallsorpacktheargumentsandsendthemtoanobjectinanotherprocessand/oronanothermachine.Youalso
can'taskarandomobjectwhetheritimplementsthegiveninterface(inlanguageterms,whetheritsclassisderivedfroma
givenabstractbaseclass).

IftheonlylanguageyouuseheavilyisC++,it'spossiblethatyoudon'trealizethatyoumightwanttodothesethingsatall,
orevenmemorizedelaboratearguments"proving"thatthesethingsshouldnotbedone.Butheyatleastabstractclasses
don'tmakeanythingworsethanitalreadywasinC.QuiteanachievementforaC++feature.

[22.4]Whatisa"purevirtual"memberfunction?
FAQ:It'savirtualfunctionwhich(normally)hasnoimplementationinthebaseclass,and(always)mustbeimplementedin
aderivedclasstomakeitnonabstract.Thesyntaxis:virtual result funcname(args) = 0;.

Thisdeclarationmakestheclassabstractitisillegaltocreateobjectsofthisclass.Aderivedclassthatdoesn'timplement
atleastonepurevirtualfunctionisstillabstract.Onlyderivedclasseswithoutanyunimplementedpurevirtualfunctionscan
beinstantiated(youcancreateobjectsoftheseclasses).

FQA:Thesyntaxisridiculous.Youmaywonderwhatvirtual result funcname(args) = 1999;means.Well,itmeans


nothingitdoesn'tcompile.

Onepossiblemotivationforthissyntaxistosaveakeyword(suchaspureorabstract).Themorenewkeywordsthereare,
the"less"C++iscompatiblewithC,orwithC++codewrittenbeforethenewkeywordwasintroduced(well,strictlyspeaking,
eithertwothingsarecompatible,ortheyarenot,butwe'llignorethatforthemoment).That'sbecauseCandC++have
grammarswhichdisallowtousekeywordsasidentifiers.Thisproblemissharedbythemajorityofprogramminglanguages.

However,C++doeshaveahugeamountofnewkeywords.Thismakesonewonderwhytheveryrarelyusedexplicit(not
tomentionexport)isakeyword,whilethemanydifferentusesofthekeywordstaticareinfactcollapsedintoasingle
keywordinsteadofusingnewkeywordsforthenewuses.Andwhynotusethesilly,butstandard"reservednamespace"
(namesprefixedwithtwounderscoresorasingleunderscorefollowedbyacapitalletterarereservedforthecompiler),the
wayit's(mostly)doneinC99?Thenwe'dhave__explicitbuiltinandexplicitwouldbea#defineyou'd#includefrom
<shiny_new_useless_cxx_features>(notrailing.h,ofcourse).Thisway,yougiveanormallylookingkeywordtopeoplewho
needit,anddon'tbreakthecodeofthosewhodon't.

Here'saproposalforthenextC++standard:let'sdefinetwokeywords,__0and__1.Withatokensequencecomposedof
thesetwokeywords,wecanexpressanything(actually,onekeywordisenough,butthat'sjusttooverbose).Thenwewon't
everneedanynewkeywords.Asthepurevirtualsyntaxexampleshows,thereadabilitylossisasmallpricetopayforthe
forward,backwardanddownwardcompatibilityachievedusingthisapproach.

http://yosefk.com/c++fqa/fqa.html 82/112
2/26/2015 C++ Frequently Questioned Answers

[22.5]Howdoyoudefineacopyconstructororassignmentoperatorfora
classthatcontainsapointertoa(abstract)baseclass?
FAQ:Ifyoudon'twanttomakea"deepcopy"ofthatpointer,there'snothingspecialaboutthiscase.

Ifyoudowanttomakeadeepcopyofthepointer(whichyounormallyshoulddowhentheclass"owns"it),theabstract
baseclassshouldhavevirtualcopyandassignmethodsyoucancallfromyourcopyconstructorandassignmentoperator.

FQA:ThisisasmallexampleofhowC++forcesyoutowritecodewhichcouldbegeneratedautomatically.Youcanavoid
theproblembyavoidingtheownershipapproachtolifetimemanagement(RAII),butfiguringoutthatyouneedthesevirtual
functionsandimplementingthemiseasyforpeoplewhounderstandC++well.

ThetroubleisthatmostpeopleusingC++don'tunderstanditverywell.C++hasthelethalcombinationoflookingallnice
andsimpleonthesurfaceandhavinglotsoftrapsinstalledunderthesurface,waitingforavictim.Theonlychanceofthe
victimistohaveaverygoodunderstandingoftheunderlyingproblemsofC++.Withthatunderstanding,it'seasytoseethat,
um,youhavetomakeadeepcopysinceyou'rethe"owner",andanobjectpointedbytwoownersisgoingtobewipedout
twicebythedestructor,andwedon'twantthat,solet'scopytheobjectcostly,butsafe,and,um,wecan'tjustcopythe
object,becausewedon'tknowitstype,butwait,theobjectitselfdoesknowitstype,soweneedittohelpuswiththe
copying,soweneedtoaddthesevirtualcopyfunctionstothishierarchyofclasses.It'sagoodthingwediditnowbeforethe
interfacesbecamestableandaddingfunctionsbecamearoyalpain,causingrecompilationofcallingcode.Ordidwe?

Theproblemwithallthisreasoningisthatithaslittletodowithwhateveryou'reultimatelytryingtoachieveinyourprogram.
Somanypeoplewhothinkmoreaboutwhattheirprogramdoesthanaboutthewaytheirprogramminglanguageworks
won'tseethiscoming,anddosomethingwrong.No,itdoesn'tmeanthatthepeopleprimarilyfocusedontheprogramming
languagearemoreproductivethanothers.Ofcoursetheyaren'tuniformlylessproductive,either.Someofthepeoplewitha
programminglanguagefocusspendmostoftheirtimechoosingbetweenfunc(obj)andobj.func(),somedon'titdepends
ontheperson,andpeoplecanchange,furthercomplicatingmatters.

Ofcoursethisproblemexistswithallcomputerlanguagesand,moregenerally,withallsoftwaresystems,and,more
generally,withallformalsystems.Basicallythere'stheicethethingscompatiblewithhumancommonsenseandthecold
waterunderit,intowhichyoucanfallwhentherulesgoverningthesystemcontradictyourcommonsense.Sowhat'sso
specialaboutC++?

Well,inC++,theverythiniceiscoveredwithpaint,andthewaterisdeepenoughtodrown.

Inheritancewhatyourmothernevertoldyou
Note:sectionnamesarecopiedverbatimfromtheFAQ.Thedocumentisnotbasedontheassumptionthatitwasyour
motherwhotoldyoutheotherthingsaboutinheritance.

[23.1]Isitokayforanonvirtualfunctionofthebaseclasstocallavirtualfunction?
[23.2]ThatlastFAQconfusesme.Isitadifferentstrategyfromtheotherwaystousevirtualfunctions?What'sgoing
on?
[23.3]ShouldIuseprotectedvirtualsinsteadofpublicvirtuals?
[23.4]Whenshouldsomeoneuseprivatevirtuals?
[23.5]Whenmybaseclass'sconstructorcallsavirtualfunctiononitsthisobject,whydoesn'tmyderivedclass's
overrideofthatvirtualfunctiongetinvoked?
[23.6]Okay,butisthereawaytosimulatethatbehaviorasifdynamicbindingworkedonthethisobjectwithinmy
baseclass'sconstructor?
[23.7]I'mgettingthesamemesswithdestructors:callingavirtualonmythisobjectfrommybaseclass'sdestructor
endsupignoringtheoverrideinthederivedclasswhat'sgoingon?
[23.8]Shouldaderivedclassredefine("override")amemberfunctionthatisnonvirtualinabaseclass?
[23.9]What'sthemeaningof,Warning: Derived::f(char) hides Base::f(double)?
[23.10]Whatdoesitmeanthatthe"virtualtable"isanunresolvedexternal?
[23.11]HowcanIsetupmyclasssoitwon'tbeinheritedfrom?
[23.12]HowcanIsetupmymemberfunctionsoitwon'tbeoverriddeninaderivedclass?

[23.1]Isitokayforanonvirtualfunctionofthebaseclasstocallavirtual
function?
FAQ:Sometimesitis.SupposeyouhaveaclassAnimalwithanonvirtualgetAwfullyExcited()method.Inyoursystem,
allanimalsdoitsimilarly:

http://yosefk.com/c++fqa/fqa.html 83/112
2/26/2015 C++ Frequently Questioned Answers
void Animal::getAwfullyExcited()
{
makeExcitedNoises(); // all animals make different noises
cout << "And here comes the dance!" << endl; // all animals always warn people before they dance
danceExcitedly(); // all animals dance differently
}

Sothereyouhaveitanorderlyhierarchyofanimals,eachgettingexcitedaccordingtothestandardprocedureinitsown
uniqueway.

FQA:ThetroublewiththiswholethinginC++isthatyoucan'teasilytellwhichfunctionscanbeoverriddenandwhichcan't,
andwhat"override"means.

Thedefaultis"can't"youhavetoexplicitlysayvirtualtoenableoverriding.Unlessyouderiveyourclassfromabase
classhavingvirtualfunctionswhenyouoverridethosefunctions,thevirtualkeywordbecomesoptional.Butevenifthe
functioninthebaseclassisnotvirtual,youstillcanoverrideitexceptthatnowthebindingisstatic:ifyoucallafunction
throughapointerstaticallytypedasBase*,thebaseclassimplementationiscalled,butifyoucallitthroughaDerived*,the
derivedclassimplementationiscalled.Soit'sadifferentkindof"overriding".Andnaturallyyoucanhavemorethanonelink
inthechainofderivedclasses.

Backtoourquestion,itisgenerallyOKtohaveacommonbaseclassimplementationcallfunctionsdefinedinthederived
classesinmanycasesthatdoesexactlywhatyouwant.However,inthespecificcaseofC++virtualfunctionsitmay
becomehardtofigureoutwhichfunctionsarevirtualandwhicharenot.

Soit'ssometimesbettertoseparateAnimal(havingonlypurevirtualfunctions)andEmotionalBehavior(havingmethods
takingananimalandcallingitsfunctionstoimplementvariouscommonrituals).No,it'sprobablynotagoodideatoaddthis
ruletoyourlocalCodingConventionsDocumentiftheclassisrelativelysmallandsimple,there'snopointincreatingmore
codebysplittingittoseveralclasses.ThethingisthatC++classeswithmanymethods,somevirtualandsomenot,
especiallywhentheyarepartofcomplexhierarchieswithlotsofoverridingofbothkinds,endupmakingpeoplewonderwhy
thispieceofcodewascalled.Why,why,why?..

[23.2]ThatlastFAQconfusesme.Isitadifferentstrategyfromtheother
waystousevirtualfunctions?What'sgoingon?
FAQ:Yes,therearetwodifferentstrategiesrelatedtotheuseofvirtualfunctions.Inthefirstcase,youhaveacommon
nonvirtualmethodinthebaseclass,butusevirtualmethodstoimplementthepartswhichdodiffer.Inthesecondcase,
youhavevirtualmethodsimplementeddifferentlyinderivedclasses,buttheycallcommonnonvirtualmethodsinthe
baseclass.Thesecommonbitscanalsobeimplementedsomewhereelsenotnecessarilyinthebaseclass.

Sometimesyouusebothstrategiesinthesameclassoneforsomeofthemethods,theotherforothermethods.That's
OK,too.

FQA:Well,sortof,yeah.Isitjustmeordidwereallylearnnothingatall?Thislengthydiscussionfollowsquitedirectlyfrom
firstprinciples.virtualfunctionsallowdifferentderivedclassestoimplementamethoddifferently.Allfunctions,including
nonvirtual,canbecalledonceormorefromvariousplaces.Doessomethingtotallyobviousfromtheserulesdeservethe
pompousname"strategy"?

No,it'snotjusttheFAQ.Thisisverycommoninthe"softwareengineering"community,especiallyintheC++subculture.
Let'slookatanexample.You'veprobablyseenmethodsthatcreatenewobjectsofclassesderivedfromacommonbase.
Suchmethodsareusefulbecausetheircallerdoesn'thavetobeawareofthedifferentderivedclasses.Forexample,you
canhaveacreateMovieReader(filename)methodthatchecksthefiletypeandcreatesanMPEGReaderoranAVIReaderor
whatever,andwhoevercallscreateMovieReaderdoesn'thavetocareaboutthemanydifferentkindsofreaders.Isthisworth
aspecialtermaccompaniedbyawholediscussion?Well,ithasatermit'stheFactoryMethodDesignPattern.Sometimes
youhaveanabstractbaseclasswithnothingbutFactoryMethods.Thishasanameofitsown,tooit'stheAbstractFactory
DesignPattern.

Thenamesusedbypeoplerevealalotaboutthem.Forexample,thepeoplelivingclosetoNorthPolehaveatwodigit
numberofnamesfor"snow".Clearly,thereasonisthattheirvisualdietiscomposedprimarilyofsnow,sotheyknowalot
aboutthedifferentkindsofsnowandneverconfusethem.Buttreesthosetheycomeacrossonceinalifetime.Nopointin
havingmanynamesfortrees.Atree,youknow,thatdark,highthingwithmessystuffstickingout.

Thistellsussomethingabouttheintellectualdietofpeoplecallingtrivialcombinationsofbasiclanguageconstructs
"strategies"and"patterns".OfcoursethesepeopleloveC++lookatallthosedifferentstringclasses,andallthosewaysto
implementstillnewones!Somuchsnowtoplaywith.

Disclaimer:myknowledgeofanthropologyisapproximatelyzero.Therefore,it'sbettertoconsidertheNorthPoleexample
abovetobehypotheticalthantomakecriticaldecisionsassumingit'sliterallytrue.
http://yosefk.com/c++fqa/fqa.html 84/112
2/26/2015 C++ Frequently Questioned Answers

[23.3]ShouldIuseprotectedvirtualsinsteadofpublicvirtuals?
FAQ:Well,firstofallavoidstrictrulessaying"neverdothis,alwaysdothat".Asaruleofthumb,experiencetellsthatmost
ofthetimevirtualfunctionsarebestmadepublic,withtwonotableexceptions.First,therearefunctionswhicharesupposed
tobecalledonlyfromthebaseclass,thewaydescribedintheprevioustwoFAQs.Andsecond,there'sthePublic
OverloadedNonVirtualsCallProtectedNonOverloadedVirtualsIdiom:
class Base
{
public:
void overloadingTotallyRules(int x) { butWeDontWantToOverloadVirtualFunctions_int(x); }
void overloadingTotallyRules(short x) { butWeDontWantToOverloadVirtualFunctions_short(x); }
protected:
virtual void butWeDontWantToOverloadVirtualFunctions_int(int);
virtual void butWeDontWantToOverloadVirtualFunctions_short(short);
};

Thissolvesanimportantproblem:overloadingtotallyrules,butwedon'twanttooverloadvirtualfunctions.ThePublic
OverloadedNonVirtualsCallProtectedNonOverloadedVirtualsIdiommakeslifeeasyforclassusersandthe
implementorsofderivedclasses!Clearlyyou,theauthorofthebaseclass,absolutelymustclobberyourcodewiththis
nonsensetomakeeveryone'slifebetter!Thinkaboutthereducedmaintenancecostsandthebenefitofthemany,you
selfishcodegrinder.

FQA:Here'sasimpleanswertoyourquestion,triviallyfollowingfromthedefinitionsandwithouttheneedtocreatea
taxonomyofrulesandexceptions.C++accesscontrolisforclarity:youwanttomakeitclearwhichpartsoftheclassare
supposedtobeusedandwhicharejustimplementationdetails.Thiscanmakeiteasiertounderstandyourcodeand
preventspeoplefromusingthebitsthatyoumightwanttochangelater.

Therefore,ifyoudon'tthinkthatanyoneoutsideoftheclasshierarchyisgoingtouseavirtualmethod,makeitprotected.
Otherwise,makeitpublic.Inparticular,youcanstartwithprotectedandchangeittopublicifitturnsoutyouwerewrong.
That'sall.Whyisanyspecialcaseofthisparticularlyinteresting?

AstotheOneKindOfFunctionCallsAnotherKindOfFunctionIdiomrememberthesnowexample?Well,nowweare
deepinsideapileofsnow,coiningnamesforeachindividualsnowflake.Iwonderifthere'saFunctionIsPassedA
ParameterToConfigureItsOperationIdiom.No,thereprobablyisn'tafterall,it'snotObjectOriented.

Moreimportantly,the"idiom"isanonsolutionfortheproblemswithoverloading.Allwegotisextralayersofcodepilingup.
Ultimately,thepeoplewillhavetoreadthiscodetofigureoutwhattheprogramdoes,andthelayersofindirectionaddingno
functionalityatallwillconfusethemandoccupytheirshorttermmemoryinsteadofother,actuallyusefuldetails.Whynot
simplyavoidoverloadinginthiscase?

Talkingabout"reducingmaintenancecosts"doesn'tbyitselfactuallyreduceanymaintenancecosts,youknow.

[23.4]Whenshouldsomeoneuseprivatevirtuals?
FAQ:Probablynever.Itconfusespeople,becausetheydon'tthinkprivatevirtualscan'tbeoverridden,buttheycan.

FQA:TheFAQisrightthebehaviorofprivate virtualisridiculousitcompiles,butforthewrongreasons.Notethatthere
aremany,manymorethingsinC++thatprimarilyconfusepeople.OneexcellentreasontoavoidC++altogether.I'mnot
joking.Nothingfunnyaboutit.Well,maybeitisfunnythatC++developersareconfusedforaliving,butthat'sacruelkindof
humor.

[23.5]Whenmybaseclass'sconstructorcallsavirtualfunctiononitsthis
object,whydoesn'tmyderivedclass'soverrideofthatvirtualfunctionget
invoked?
FAQ:SupposeyouhaveabaseclasscalledBase,callingavirtualfunctionfinitsconstructor.Then,whenobjectsofa
derivedclasscalledDerivedarecreated,Base::virtiscalledfromBase::Base,notDerived::f.

ThereasonisthatwhenBase::Baseexecutes,theobjectisstilloftypeBase.ItonlybecomesanobjectoftypeDerivedwhen
thecodeinDerived::Derivedisentered.IfyouwonderwhyC++worksthisway,considerthefactthatDerived::fcould
accessuninitializedmembersoftheclassDerivedifitcouldbecalledfromBase::Base,whichrunsbeforeDerived::Derived
initializesthemembersofDerived.

Luckily,C++doesn'tletthishappen,preventingsubtleerrors!

http://yosefk.com/c++fqa/fqa.html 85/112
2/26/2015 C++ Frequently Questioned Answers
FQA:Here'swhatactuallyhappens.Derived::DerivedcallsBase::Base,andthenitsetsthevptrtopointtotheDerived
vtable.SettingthevptrbeforecallingBase::Basewouldn'twork,becauseBase::BasesetsthevptrtopointtotheBasevtable.
Base::Basedoesn'tknowthatit'scalledinordertoultimatelyinitializeaDerivedobjectthecodeofBase::Baseand
Derived::Derivediscompiledseparately(correction).That'swhat"theobjectisstilloftypeBase"reallymeans.

Now,there'savalidargumentagainstdescribingthemechanismsoftheimplementationinordertoexplainthebehaviorofa
system.Thesystemisbuiltbypeopleforotherpeople.Itsbehaviorissupposedtomakesense.Ifitdoesn't,andcanonlybe
explainedbylookingintotheimplementationinsteadoftheneedsoftheuser,it'saprobleminthesystem.Sometimessuch
problemsseemtobeinevitable.Butwheneverpossible,it'sbesttodiscusswhyacertainbehaviorisreasonableinthe
situationasperceivedbytheuser,andonlytalkabouttheimplementationwhenabsolutelynecessary.However,this
argumentisrarelyapplicabletoC++.

First,C++makesverylittlesensefromtheuser'sperspective.Itonlymakessensefromtheperspectiveofthelanguage
designer,providedthatseveralaxiomsofquestionablevalueareaddedtoit(suchas"alanguagemustlookcompatiblewith
C,althoughitdoesn'thavetoreallybecompatible","allbuiltintypesshouldbethosefoundinC,unlesstheyareanewkind
ofpointer",etc.).Forexample,itisreasonablethatBase::Basecan'tcallDerived::f(well,sortofitdependsonwhatyou
thinkaboutthewayC++handlesobjectconstructioningeneral).ButisitreasonablethatBase::Basecancallavirtual
methodBase::fbysimplysayingf()?Howoftenisthatwhatyouwant?Thisquestionisirrelevant,becauseinC++,if
somethingbecomestechnicallypossibleasasideeffectofsomelanguagemechanism,ittendstobelegal.Forexample,
whydoesprivate virtualfromthepreviousFAQcompile?Theanswerissimple:whynot?

ThesecondreasontodescribebehaviorintermsofimplementationisthatruntimeerrorscauseC++programstocrashin
waysundefinedatthesemanticalspecificationlevel.Itistheoreticallypossibletoreadtheentirecodeoftheprogramand
findthesemanticallyillegalcode.Inpractice,you'llhavetofindtheerrorbylookingattheexecutionoftheprogram(when
youarelucky)oratasnapshotofitsfinalstatebeforethedeath(whenyou'renot),andtryingtounderstandhowthingscan
behavethisway.Andyoucan'tdothatwithoutunderstandingtheimplementation.

[23.6]Okay,butisthereawaytosimulatethatbehaviorasifdynamic
bindingworkedonthethisobjectwithinmybaseclass'sconstructor?
FAQ:Yes.It'sanIdiom,ofcourse.Namely,theDynamicBindingDuringInitializationIdiom.

Oneoptionistohaveavirtual initfunctiontobecalledafterconstruction.Anotheroptionistohaveasecondhierarchyof
classes,whichdoesn'talwayswork,but...(sorry,Icouldn'tmakeitthroughallthecodelistings.Ifyoulikelotsofhierarchies
ofclassesandfindthissolutioninteresting,pleasefollowthelinktotheFAQ'sanswer).

Thefirstapproachhastheproblemofrequiringanextrafunctioncalluponinitialization.Wecanrelyontheselfdisciplineof
theprogrammers(theselfdisciplineisespeciallyimportantwhenexceptionscanbethrownbyinitmakesureyourelease
theallocatedobjectproperly),orwecanwraptheconstructionandtheinitcallinasinglecreatefunctionreturninga
pointertotheobject.Thelatterrulesoutallocationonthestack.

FQA:Weseemtobemakingprogress.Let'ssee:wegotridoftheallocationonthestack,sowenolongerneedtoknowthe
privatemembersofclasses.Andifwehadgarbagecollection,exceptionsafetywouldnolongerbeaproblem,either.Too
badC++classesandmemorymanagementcan'tbechanged.Orcanthey?

Howabouttryinganotherprogramminglanguage?

[23.7]I'mgettingthesamemesswithdestructors:callingavirtualonmy
thisobjectfrommybaseclass'sdestructorendsupignoringtheoverridein
thederivedclasswhat'sgoingon?
FAQ:Again,you'rebeingprotectedbythecompiler.Protectedfromyourself!Youcouldaccessmembersthatwerealready
destroyedifthecompilerletyoudowhatyouwant.

WhenBase::~Baseiscalled,thetypeoftheobjectischangedfromDerivedtoBase.

FQA:Thanksfortheprotection.Atleastthebehaviorissymmetrical.

Protectmefromaccesstodestroyedobjectsthroughdanglingreferencesinthegeneralcasenexttime,willyou?

[23.8]Shouldaderivedclassredefine("override")amemberfunctionthatis
nonvirtualinabaseclass?
http://yosefk.com/c++fqa/fqa.html 86/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:Youcandothat,butyoushouldn't.

Experiencedprogrammerssometimesdothatforvariousreasons.Rememberthattheuservisibleeffectsofbothversions
ofthefunctionsmustbeidentical.

FQA:Here'satradesecret:notsoexperiencedprogrammersdothat,too.Fortheumpteentime:whydoesthiscompile?
Thisparticularcasedoesn'tseemtobeanunintendedsideeffectit'safeaturewithelaboratedesign(there'sallthis
nonsensewithusingnamesfromthebaseclassshadowedbyfunctionswiththesamename,etc.).

Theredefinitionlookinglikeanoverrideisoverloadingonsteroids:it'sevenlessusefulandhasevenhigherobfuscation
potential.Andit'sonlyoneofthezillionsofvariousnamebindingrulesthebitsofC++makingitimpossibletodecipher
whatcodeisactuallycalledbyf(x).

[23.9]What'sthemeaningof,Warning: Derived::f(char) hides


Base::f(double)?

FAQ:Whatdoyouthinkitmeans?You'regoingtodie.

It'slikethis:Derived::f(char)doesn'toverrideBase::f(double)ithidesit.Inotherwords,itmakesitimpossibletocall
Base::f(double)viaaDerived*.Atthesametime,Derived::f(char)cannotbecalledviaBase*.

FQA:"You'regoingtodie",warnstheFAQ.Well,accordingtoapopulartheory,allofusare.However,thisinterestingfact
doesn'tseemtobelonghere.C++surelyisdepressing,butI'mnotawareofanydatashowingacausalrelationshipbetween
usingC++andsuicideorlethalbraindamage.

No,really,whyishidinganamealethalbug?Sure,itmakestheprogrammoreobscure,but,duh,thisisC++.Theworst
thingthatcanhappenisthatsomeonewillcallBase::fwithacharandBase::f(double),notDerived::f(char)willget
called.Sowhat?Similarthingshappenwithoverloadingwithoutanyinheritanceinvolved.Doyoureallyknowtheimplicit
conversionrulesbetweendifferenttypes,andcanpredictwhathappenswhenyoupassaninttoanoverloadedffunction
whichonlyhasacharandadoubleversion?Ibetyoucan'tdoitwhenthingsgetalittlebitmorecomplicated.Nonormal
personcan.

C++overloadingisanightmare.Usingitisnaiveorstupid,dependingonone'sexperience.Manylanguages,bothstatically
anddynamicallytyped,don'thavecompiletimeoverloadingbasedonargumenttypes.Haveyoueverheardaprogrammer
usingsuchalanguagecomplainaboutit,orbecomeveryenthusiasticaboutC++overloading?Whatproblemdoes
overloadingsolve?OK,supposeitimprovesclarity(averyquestionableclaim).Doyoureallythinkthatoverloadingshould
cometogetherwithatonofimplicitconversionrules,andatypesystemwithatonofspecialcases(cvqualifiers,
pointers/arrays/references,single&multipleinheritance,templates...)?Whenoverloadingdoescomewiththeextratonof
rules,doesitstillmaketheprogrammoreclear?What'sthat?"Compiletimepolymorphism",yousay?YoumeanC++
templates?Iseewhatyou'reupto.Happydebugging,pal.

[23.10]Whatdoesitmeanthatthe"virtualtable"isanunresolvedexternal?
FAQ:Well,asyouknow,"unresolvedexternal"meansthatthere'safunctionoraglobalvariablethatyourcodedeclares
anduses,butneverdefines.AvirtualtableisaglobalvariabledeclaredimplicitlybyatypicalC++implementationforeach
classwithatleastonevirtualfunction.

Now,normallywhenyouforgettodefineavirtualfunction,you'llgetan"unresolvedexternal"errorsayingthatthisfunction
ismissing.Butinmanyimplementations,ifyouforgetthefirstvirtualfunction,thewholevirtualtablewillbecome
"unresolved".That'sbecausetheseimplementationsdefinethevirtualtableatthetranslationunitwherethefirstvirtual
functionisimplemented.

FQA:GAAA!!SoTHAT'Swhyyouhavetodefinestaticclassvariablesexplicitlyinyour.cppfile,butdon'thavetodefine
vtablesexplicitly!ThisissoooSTUPID!I'mshocked.Waitasecond.Letmerecover.

OK,here'showitworks.InC++,there'sreallynosuchthingas"aheaderfiledefiningtheclass"and"a.cppfile
implementingitsfunctions".It'sjustaconvention.Accordingtotherules,thedefinitionoftheclassmemberscanbespread
acrossseveral"translationunits",andeach"translationunit"caninturnbespreadacrossseveralfiles#includingeach
other.ThisisinheritedfromC,andinteractsbadlywiththenewfeaturesinC++.

Forexample,considerthosevirtualfunctions.Youprobablyneedatableofthose,whichissimilartoaglobalCvariable.Of
courseyoudon'twanttohavetheC++programmerimplementthetablemanually,thewaythey'ddoitinCorelsewhat's
thepointofthevirtualkeyword?Butwhereshouldthevtablebeimplemented?Inthe.cppfileofaclass?Where'sthat?

Withvtables,there'sa"solution".Afterall,wedon'tneedavtableunlesswehavesomevirtualfunctions,dowe?Well,then,
http://yosefk.com/c++fqa/fqa.html 87/112
2/26/2015 C++ Frequently Questioned Answers
oneofthesefunctionshastobethefirstone.Whynotplacethevtablenearthedefinitionofthatfunction?Thisisagood
place,becauseitwon'tget#includedtwice(ortheuserwillgeta"multipledefinition"erroranyway).

Andthentherearethestaticclassvariables.Wheredowestuffthose?Well,um,thereseemstobenogoodplaceatalla
classcouldconsistofasinglestaticmember.Noanchorintheseaofsourcecodefloatinginthefilesystem.Oh,well,we'll
havetheuserchooseaplaceforaduplicateType Class::member_name;variabledefinition.Alittlebitmoretypingisnotthat
bad.

Iwonderwhattheydowithvirtualfunctionsimplementedinthebodyofaclassthough.Ialwayswonderedaboutthose.Of
coursetheycangeneratemanyvtablesandthrowawayallcopiesbutonethewaytheydowithtemplates.Butthatwon't
workwithalinkeronlysupportingC.Maybetheydidn'tallowtoimplementnoninlinefunctionsinthebodyofaclassbefore
thebravedecisiontoaddfeaturestothelinker.Anyoneknowledgeableaboutthehistoryofthesubjectiswelcometo
enlightenme.However,theknowledgeofthehistoryofthesubjectcan'tpossiblymakethiswholebusinessseemless
stupidtoalanguageuser.

[23.11]HowcanIsetupmyclasssoitwon'tbeinheritedfrom?
FAQ:Youcanhavetheconstructorsprivate.Theobjectswillhavetobecreatedbypublicfunctionsdelegatingtothe
constructor.

Alternatively,youcancommentthefactthatyoudon'twanttheclasstobeinheritedfrom:// if you inherit from this


class, I'll hunt you down and kill you.

There'sathirdsolution(WARNINGthisonecanrotyourbrain):youcaninherityourclassfromaprivate virtualbase
class,whichhasaprivateconstructoranddeclaresyourclassafriend.Thisway,ifsomeonetriestoinheritfromyou,
they'llneedtodirectlycallthebaseclassoftheconstructor,whichwon'tcompile,sincetheconstructorisprivate.Thiscan
addanextrawordofmemorytothesizeofyourobjectsthough.

FQA:C++doesn'thavefinal.Itprobablyisn'tabigdeal,especiallyconsideringthefactthatifitdidhavefinal,itwouldbe
littlemorethanacomment,justlikeprivateislittlemorethanacomment.Sothecommentinsteadofakeywordisprobably
thebestapproach.

Theotherapproachesyieldcrypticcompiletimeerrormessages.ManypeopleintheC++communitybelievethatacryptic
compiletimeerrormessageisagoodthing.Thisisprobablyreasonableifyouonlycareabouttheory("earlyfaultdetection
isgood"),andignorepractice(easyfaultdetectionisgood,andrunningaprogramshouldbeeasierthandeciphering
stronglyencryptedC++compilererrormessages,whichtendtocomeinlargecascades).

Havingnorealexperiencewithotherlanguageshelpsonetosticktothisbizarrepointofview.C++compilesveryslowly,so
peoplewhoneverworkedwithanythingelsedon'tthinkthatrunningaprogramiseasy.C++codeisalsohardtodebug,so
peopledevelopafearofruntimeerrors.

[23.12]HowcanIsetupmymemberfunctionsoitwon'tbeoverriddenina
derivedclass?
FAQ:Usea/* final */commentinsteadofafinalkeyword.It'snotatechnicalsolutionsowhat?Theimportantthingis
thatitworks.

FQA:SowhydoesC++haveprivate?It'snothingbutacommentrecognizedbythecompiler.

Therealanswerisasfollows.Ifafunctionisnotvirtual,itshouldn'tbeoverridden,astheFAQitselfhasalreadyexplained.
Sothelackofavirtualkeywordiseffectivelyequivalenttoafinalkeyword.NowifC++didn'tallowtooverridenon
virtualmethods,andifitwouldconsistentlyrequiretousethevirtualkeywordinallvirtualfunctiondeclarations,itwould
beprettyclearwhichfunctionsshouldn'tbeoverriddeninmostcases.

Ifyoulookfornontechnicalsolutionstooverridingproblems,considerbanningnonvirtualoverridesinyourorganization.I
didn'tgivethisoneadeepthoughtquitefrequentlywhenyoutryto"fix"C++bybanningsomeofitsfeatures,butnotothers,
yourrulesbackfire.AndIcan'tknowwhethercodingconventionsworkinyourorganizationatall(believeme,therearehuge
andverydisciplinedorganizationswherecodingconventionsarenotreallyfollowed,andtheirprimaryeffectisprogrammers
feelingangerorguiltanotherniceoptionispeoplemindlesslyfollowing"bestpractices",wreakinghavocinanorderlyway).
AllI'msayingisthatnonvirtualoverrideseemsbothuselessandlargelyindependentoftherestofthelanguageatfirst
glance,sonotusingitlookslikeagoodthing.

Inheritancemultipleandvirtualinheritance
http://yosefk.com/c++fqa/fqa.html 88/112
2/26/2015 C++ Frequently Questioned Answers
Thissectionisaboutmultipleinheritance.Whileinheritanceandvirtualfunctionsareamongthemostuseful(thatis,the
leastuseless)C++features,C++multipleinheritanceisattheotherendofthespectrum.

[25.1]Howisthissectionorganized?
[25.2]I'vebeentoldthatIshouldneverusemultipleinheritance.Isthatright?
[25.3]Sotherearetimeswhenmultipleinheritanceisn'tbad?!??
[25.4]Whataresomedisciplinesforusingmultipleinheritance?
[25.5]Canyouprovideanexamplethatdemonstratestheaboveguidelines?
[25.6]Isthereasimplewaytovisualizeallthesetradeoffs?
[25.7]Canyougiveanotherexampletoillustratetheabovedisciplines?
[25.8]Whatisthe"dreadeddiamond"?
[25.9]WhereinahierarchyshouldIusevirtualinheritance?
[25.10]Whatdoesitmeanto"delegatetoasisterclass"viavirtualinheritance?
[25.11]WhatspecialconsiderationsdoIneedtoknowaboutwhenIusevirtualinheritance?
[25.12]WhatspecialconsiderationsdoIneedtoknowaboutwhenIinheritfromaclassthatusesvirtualinheritance?
[25.13]WhatspecialconsiderationsdoIneedtoknowaboutwhenIuseaclassthatusesvirtualinheritance?
[25.14]Onemoretime:whatistheexactorderofconstructorsinamultipleand/orvirtualinheritancesituation?
[25.15]Whatistheexactorderofdestructorsinamultipleand/orvirtualinheritancesituation?

[25.1]Howisthissectionorganized?
FAQ:TheFAQsectioncontainsboth"highlevel"issues(themeaning&purposeofthelanguageconstructs)and"lowlevel"
issues(thedetailedsemantics&implementationofthelanguageconstructs),inthatorder.Besuretounderstandthehigh
levelstuffbeforedelvingintothelowlevelstuff.

FQA:ThisFQAsectionisorganizedexactlyliketheotherFQAsectionsbycopyingthestructureoftheFAQsections.

TheFAQ'snoteaboutthetwolevelsofdiscussionisequallyapplicabletoallC++features/programminglanguages/software
systems/formaldefinitionsintheworld.Butit'slocatedhereandnotelsewhereforareason.ThereasonisthatC++multiple
inheritancemakesverylittlesenseevenbyC++standards.Inotherwords,thecaseswhereyoucanexpressausefulhigh
levelideausingtheactualfeaturesusedtoimplementmultipleinheritanceinC++arerare.Sopeopleendupnotusingit,or
abusingit,butfailtouseit"right",becauseit'sunclearwhat"right"meansinthiscontext.

TheFAQapparentlybelievesthatthissituationcanbefixedbyexplainingwhat"right"means.Let'ssitbackandwatch.

[25.2]I'vebeentoldthatIshouldneverusemultipleinheritance.Isthat
right?
FAQ:THESEPEOPLEREALLYBOTHERME!!Howcantheyknowwhatyoushoulddowithoutknowingwhatyouwant
done?!?!

FQA:Thisragemayprovokesomesympathy.We'veallmetpeoplewhodon'tseemtobedoinganythingusefulthemselves
andcompensateforitbygettinginothers'wayandtellingthemhowtodotheirjob,theirultimategoalapparentlybeingto
stopanyusefulworkaroundthem.Inparticular,languagefeatureswhichshouldreallyneverbeusedarerare.However,
languagefeatureswhichshouldbeusedreallyrarelyandwithcarefulconsiderationaremorecommon,andC++multiple
inheritanceisoneofthem.

Therearetwokindsofproblemswithmultipleinheritance"static"and"dynamic".

The"static"problemshavetodowithcompiletimenamelookup.SupposeyouderiveaclassCfromclassesAandB,and
bothhaveamethodcalledname.WhichonewillgetcalledwhensomeonecallsnameusingapointertoaCobject?Ifyou
overridenameintheclassC,didyouoverrideA::name,B::nameorboth?Whathappensifthetwonamefunctionsaccept
argumentsofthesametype?Whathappensiftheydon't?

The"dynamic"problemshavetodowiththewayobjectsoftheclassCareactuallybuilt,andtheruntimeeffectsrelatedto
it.Basically,aCobjectwillcontainanAsubobject,andaBsubobject,andthosetwowillbecompletelyunrelated.Soif
youhaveapointertoaCobject,andyou(silently)upcastittoA*,andwritecodeassumingthatyougetanobjectwhichis
derivedfrombothAandB,andcasttheA*toB*,theprogramwillcrashorworse.Whatyoushouldhavedoneisfirstcast
theobjecttoC*andthentoB*,sincewithoutknowingthedefinitionofC,there'snowaytofigureoutthelocationoftheB
subobjectgiventhelocationoftheAsubobject.ThisisonetrapevenaprettyexperiencedC++programmercanfallinto.

Youcanmemorizethesharpedges,oryoucanstayawayfromthewholething.Pickyourpoison.

[25.3]Sotherearetimeswhenmultipleinheritanceisn'tbad?!??
http://yosefk.com/c++fqa/fqa.html 89/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:Sure!Sometimes(butnotalways)usingmultipleinheritancewilllowerallkindsofcosts.Ifthisissoinyourcase,use
it!Ifitisn't,don'tblamemultipleinheritance"goodworkmenneverblametheirtools".

FQA:No,therearenosuchtimes,it'sapoorlydesignedlanguagefeature.Butitcouldbethatsometimestheotheroptions
availableinC++areevenworse.

Whilewe'reatit,let'sclarifythewholeblameissue.Ifyouchoosetouseatoolnotsuitableforyourjob,youshouldn'tblame
thetool.Well,actually,youshouldblamethevendorofthetoolifitwasadvertisedassomethingitwasn't.WasC++ever
advertisedthatway,forexample,whataboutsupportforobjectorientedprogramming?

Well,wedon'tevenneedtodiscussthat,becauseaprogramminglanguageisnotexactlyatool.Itismoreaccurately
described,well,asalanguage.Thekeydifferencebetweentoolsandlanguagesinthecontextof"blame"ischoice.You
probablydon'tchoosetospeakEnglishyoudosoinordertocommunicatewithalltheotherpeoplespeakingEnglish.
Whenabunchofpeopledosomethingbecauseotherpeopledoit,too,it'scalled"networkeffects".Forexample,ifyouwant
toworkonaprojectforreasonshavingnothingtodowithcomputerlinguistics,andtheprojectusesC++,you'llhavetouse
C++,too.Nochoice.

Sothat'sthedifferencebetweenalanguageandatool.Still,youwouldn'tblameEnglishbecauseit'ssohardtolearnor
inconsistentorwhatever,wouldyou?Well,thedifferencebetweenaprogramminglanguageandanaturallanguageisthat
thelatteris,um,natural,sothere'snobodytoblame,whiletheformerwasactuallydesignedbysomeone(well,usually).The
otherdifferenceisthecostofanerror.PeopleusuallyrecoverfrombadEnglish,computerstendtobelesstolerant.

Andthisiswhyyouseemtohavemoregroundto"blamethelanguage"thanto"blamethetools"inthegeneralcase.Of
courseyoumaynotlikethewholeattitudeof"blaming"things,etc.everybodyisfreetofeelanywaytheyfeellikeor
something.Butthathasnothingtodowithbeinga"goodworkman"(whichitselfhasanirksomesoundtoit,mindyou).

[25.4]Whataresomedisciplinesforusingmultipleinheritance?
FAQ:There'salonganswersaying3things.First,youshouldnormallydoittoachievepolymorphism,notbaseclasscode
reuse.Second,theclassesyoumultiplyinheritfromshouldnormallybepureabstract.Third,youshouldconsiderusingthe
"bridgepattern"or"nestedgeneralization"alternativestoMIdescribedbelow.

FQA:Theguidelinesareprettygood,exceptformaybe"nestedgeneralization",whichisreallyawaytoworkaroundthe
deficienciesoftheC++objectsystemratherthanareasonablewaytomodelanything.

Ifyoulike"disciplines"withoutanyreasoninghavingtodowiththeactualproblemathand,here'ssomemoreforyou.The
FAQ'sguidelinesareaspecialcaseof"don'tusedesignswhichwouldonlyworkinoneprogramminglanguage"(footnote:
especiallyifthatlanguageisC++).Specifically,theFAQ'sguidelinesprettymuchsummarizetherulesforusingmultiple
inheritanceinJava,soyourdesignwouldbeimplementableinatleasttwolanguages,whichisagoodsign.Thereasoning
behindtheavoiddesignstiedtoonelanguageruleisthatifsomethingisreallygood,manylanguageswouldhaveit,andif
yourdesigndependsonsomethingonlyavailableinonelanguage,it'sprobablybadbecauseitprobablydependsonabad
thing.ThisisthepointwherepeoplelovingtheuniquefeatureoflanguageXscreamthatthisreasoningiscompletely
moronic,butwealreadyknewthat,becausewepromisedourreasoningwouldn'trefertothespecificproblemathand,
whichisn'tverybrightbyitself.

Ifyou'reintorealreasoningandnotjust"disciplines",onenicethingabouthavingthebaseclassespureisthatthisway,you
don'thavetothinkaboutawholeclassofquestionsrelatedtoreimplementationofmethods.Forexample,ifyouinherita
RectangularWindowfromaRectangleandaWindow,andRectangleisn'tpureandithasaperfectlygoodresizemethod,is
thismethodstillgoodforRectangularWindowordoyouwantittoresizethewindow,whichtheimplementationinthebase
classobviouslywon'tdo?Andwhatifyoucan'treallyoverridetheRectangle::resizemethodbecauseitisn'tvirtual?The
problemwithreusingcodefromthebaseclassisthatmultipleinheritancefrequentlybreaksthatcode.

However,followingtheseguidelineswon'tnecessarilyeliminatetheproblemswithmultipleinheritancementionedabove.

[25.5]Canyouprovideanexamplethatdemonstratestheaboveguidelines?
FAQ:There'saverylongdiscussionofanexamplewithdifferentkindsofvehicleshavingdifferentkindsofengines.The
FAQproposestouseMI,orthe"bridgepattern"or"nestedgeneralization"."Bridgepattern"meansthatvehicleobjectskeep
pointerstoengineobjects,anduserscanpassmanydifferentkindsofenginetoanobjectofthesamevehicleclass.
"Nestedgeneralization"meansthatyouhavemanyclassesderivedfromVehicle(likePlane),andthenforeachsuch
derivedclassthere'sabunchofclassesderivedfromittorepresentthedifferentkindsofengine(likeOilPoweredPlane).
Tradeoffsarediscussedingreatdetail.

FQA:The"bridgepattern"(afancynameforthespecialcaseofaggregationwhenyourmemberobjecthasvirtual
functions)looksgoodhere,since,um,avehiclehasanengineandstuff.Andhencemultipleinheritancelookswrong,since
http://yosefk.com/c++fqa/fqa.html 90/112
2/26/2015 C++ Frequently Questioned Answers
anOilPoweredPlaneisn'takindofanOilPoweredEngine.

Idon'tfeellikearguingwiththeFAQ'slengthystatements,sincetheissueisn'tworthit.Thecaseswhenyoudealwiththe
definitionofnontrivialobjectmodelsarerelativelyrare.Andwhenyoudoit,youhaveenoughtimetoconsiderwhatstuff
youreallywantthemodeltosupport,andthenthinkaboutthedifferentpossibilitiestodefinethemodelandcheckifeach
possibilityreallysupportsthatstuff.Ithinkthattryingtomemorizespecialcases(callthem"patterns"orwhatever)ofobject
modelsisbasicallyliketryingtoformalizecommonsense,whichdoesn'treallywork.

Areyoustillwithmeafterthisblasphemy?Thenlet'slookatonenonproblemmentionedbytheFAQthefactthatwith
aggregation("bridgepattern"),youcan'tspecializealgorithmssuchthataspecificcombinationofvehicleandengineexhibits
aspecialbehavior.Inlanguageswhichsupportmultimethods,doingthatistrivial(multimethodsarelikevirtualfunctions,
buttheyaredispatchedatruntimebasedonthetypesofallarguments,notjustthefirstargument).AndinC++,youcan
emulatemultimethodsusingdoubledispatching(ugly,especiallywhenitbecomestriple,quadrupleandothersuchkindsof
dispatching,butstillpossible).

[25.6]Isthereasimplewaytovisualizeallthesetradeoffs?
FAQ:Here'samatrixwithcutesmiliesforya.Justdon'tapplyitnaively.

Cutematrixomittedtoavoidcopyrightproblems,aswellascutenessproblems

FQA:WARNING:there'snoknownwaytorepresentcommonsenseinatabularformatthetimeofwriting.Therefore,ifyou
choosetostorethecutematrixanywhereinyourbrain,youdoitatyourownrisk.

[25.7]Canyougiveanotherexampletoillustratetheabovedisciplines?
FAQ:Yesconsiderthecasewithland&watervehicles,whenyoualsoneedtosupportamphibiousvehicles.Thiscaseis
more"symmetric"thanthepreviousexample,somultipleinheritancebecomesmorepreferable.Still,youhavetomakesure
youreallywantitbyaskingvariousquestions(forthelistofquestions,followthelinktotheFAQ).

FQA:Um,"symmetry"isaninterestingaspectofthistofocuson,butanyway,anamphibiousvehicleisbothalandvehicle
andawatervehicle,whileanoiledpoweredplaneisaplane,butisnotanoilpoweredengine.Soyes,multipleinheritance
seemsmoreappropriate,andyes,it'swisetothinkaboutthethingsyouultimatelywantyourobjectmodeltosupportbefore
definingit.

We'llusetheopportunitytoshowhowtomodelthisproblemeffectivelyusingmultipleinheritance(implementationof
multipleinterfacesbythesameclass)withoutreallyusingC++multipleinheritance(andthusavoidingsomeofits
problems).I'mnotsayingthatthisalwaysbetterthanrealC++multipleinheritance,justthatitsometimescanbe.
class AmphibiousVehicle {
class WaterVehicleImpl : public WaterVehicle {
WaterVehicleImpl(AmphibiousVehicle* p) { /* save p */ }
...
};
// similarly, there's a LandVehicleImpl class derived from WaterVehicle
WaterVehicleImpl _water;
LandVehicleImpl _land;
public:
AmphibiousVehicle() : _water(this), _land(this) {}
WaterVehicle& getWaterVehicleIF() { return _water; }
LandVehicle& getLandVehicleIF() { return _land; }
};

Thisway,youwritemorecodethanwithmultipleinheritance,whichisbad.Itgetsevenuglierifyouwanttosimulatevirtual
inheritance,whichisbadifWaterVehicleandLandVehicleinheritfromanonabstractbaseclassVehicle(notnecessarily
recommendedbyitself).Andyouhavetocallgetfunctionsinsteadofimplicitupcasts,whichmaybeconsideredgoodor
bad.Andtherearenoproblemssuchascollisionsbetweennamesofthemembersofthebaseclasses(whichisgood).

[25.8]Whatisthe"dreadeddiamond"?
FAQ:It'swhentherearecirclesintheinheritancegraph.Here'sthesimplestcase:Derived1andDerived2areinheritedfrom
Base,andJoinisinheritedfrombothDerived1andDerived2.Thecircleinthegraphmaylooklikeadiamondifyour
imaginationworksthatway.

TheproblemisthatJoinobjectshavetwoBasesubobjects,soeachdatamemberiskepttwice.Whichiswhythediamond
iscalled"dreaded".

Theresultingambiguitiescanberesolved.Forexample,whenyouhaveaJoinobjectandrefertoits_xvariableinherited
http://yosefk.com/c++fqa/fqa.html 91/112
2/26/2015 C++ Frequently Questioned Answers
fromBase,youcantellthecompilerwhichoneyoumeanusingDerived1::_xorDerived2_::x.WhenyouupcastfromJoin*
toBase*,youcanpickoneofthetwoBasesubobjectsbyfirstcastingthepointertoDerived1*orDerived2*.Butthisis
almostalwaysnottherightthingtodo.Therightthingtodoisusuallytotellthecompilertokeepasinglesubobject.

FQA:MostC++programmersouttheredon'tunderstandwhywouldanyonesay(Derived1*)pJoininacontextwherea
Base*isexpected.ThisbyitselfisagoodreasontoavoidhavingtwosubobjectsofBaseinJoin.

Ifyoufeelthatthingsaregettingpointlesslycomplicatedatthispoint,itmaybeanindicationofgoodtaste.

[25.9]WhereinahierarchyshouldIusevirtualinheritance?
FAQ:AtthetopofthedreadeddiamondwhenyouderivefromBase,youshouldsay:
class Derived1 : public virtual Base { ... };
class Derived2 : public virtual Base { ... };

Note:whenyoudefineJoin,youcan'tconvincethecompilertokeepasingleBasesubobjectitwilldowhateverthe
definitionsofDerived1andDerived2tellittodo.Thatis,whenyoudefinetheclassesderivedfromBase,youmustplan
aheadtosupportcirclesintheinheritancegraph.

FQA:Let'sputasidethequestionwhetherthesupportforbothoptionsoneandtwoBasesubobjectsisagoodthing,and
concentrateonthewayC++givesyoutochoosebetweentheseoptions.Doingit"atthetopofthediamond"isannoying,
becauseyouhavetothinkabouttheentirehierarchywhenyoudefinetheclassesclosetoitstop.Thatis,eitherallderived
classeswillhaveseveralBasesubobjectsorallofthemwillhaveone(forcingtheusersandtheimplementersofderived
classestodealwiththeproblemsofvirtualinheritance).

Ingeneral,itisaspecialcaseofthegenericC++principlesofspecifyingeverythingintermsoftypesandtheirattributes,as
wellashavingtheuserdealwiththelowleveldetailsrelatedtounderlyinglanguagefeatureimplementation.

[25.10]Whatdoesitmeanto"delegatetoasisterclass"viavirtual
inheritance?
FAQ:Ifyouhaveadiamondlikehierarchywithvirtualinheritance,andBasehastwovirtualfunctionsfandg,thenDerived1
canimplementf,Derived2canimplementgandDerived1::fcancallDerived2::gbysimplysayingg();or(moreverbosely
andequivalently)Base::g();thatis,withoutknowinganythingabouttheexistenceofDerived2.

Thisisa"powerfultechnique".

FQA:"Powerful".Whatexactlycanyoudothiswaythatcan'tbedoneequallywellorbetterinwaysmorecleartothe
averagedeveloper?

What'sthat?Yousaythatyouonlycareabouttheenlightenedwizards(variant:thesetofwizardsconsistsofasingle
personyourself),notthemediocredroidsfromtherankandfile?Well,I'llleavetheinterestingdiscussionofyour
personalityaside.I'llleaveitasideinordertopointoutthatsomeofthepeoplewhoseprogrammingabilitiesIadmirecan't
bebotheredtolearnthequirksofC++anywherenearmylevel.Mylevel,inturn,isn'titselfanywherenear"complete"
knowledgeofthiswonderfullanguage.

[25.11]WhatspecialconsiderationsdoIneedtoknowaboutwhenIuse
virtualinheritance?
FAQ:Usuallyvirtualinheritanceisagoodideaonlyifthevirtualbaseclassandclassesderivedfromithavelittleornodata.

BTW,eveniftheyhavenodataatall,usingvirtualinheritancecanstillbebetterthannonvirtualinheritance.Forexample,if
youhavetwoBasesubobjects(withnomembers),youcanendupwithtwopointerstothedifferentsubobjects,and
comparingthemwouldtellyouthatthesearetwodifferentobjects,whichtheyaren't,atsomelevel.Quote:"Justbecareful
verycareful".

FQA:Yeah.Bevewy,vewycaweful...

TheFAQ'sadviceisaspecialcaseofitsotheradviceaboutinheritancedatainbaseclassesinteractsbadlywithMI.And
astheFAQcorrectlypointsout,nothavingdatainbaseclassesdoesn'tsolvealloftheproblems.

[25.12]WhatspecialconsiderationsdoIneedtoknowaboutwhenIinherit
http://yosefk.com/c++fqa/fqa.html 92/112
2/26/2015 C++ Frequently Questioned Answers

fromaclassthatusesvirtualinheritance?
FAQ:Derivedclassescalltheconstructorsoftheirvirtualbaseclassesdirectly.Inparticular,whenavirtualbaseclasshas
nodefaultconstructor,youhavetocallitsconstructorexplicitlyintheinitializationlistsoftheconstructorsofthederived
class.

IfthebaseclassfollowstheFAQ'sadviceaboutnothavingdatainvirtualbaseclasses,thenthebaseclassprobablyhasa
trivialdefaultconstructorandyoudon'thavetocareabouttheissuewhenyoudefinederivedclasses.

FQA:IfthebaseclassfollowstheFQA'sadvicetoavoidnontrivialconstructorsanduseinitializationfunctionswhen
needed,youdon'thavetoworryaboutinitializationofderivedclasseswithvirtualbaseclasses,either.

[25.13]WhatspecialconsiderationsdoIneedtoknowaboutwhenIusea
classthatusesvirtualinheritance?
FAQ:Don'tusedowncastsusingtheClikesyntax(Derived*)pBase.Usedynamic_cast<Derived*>(pBase).

Theanswerisunfinishedaccordingtoa"TODO"remarkinit.

FQA:Theproblemseemstobethatwithvirtualinheritance,theoffsetthatmustbeaddedtopBasetomakeitpDerived
dependsontheclassesderivedfromDerived(liketheJoinclassfromthe"dreadeddiamond"example).Sothecompiler
can'tgeneratecodeaddingaconstantoffset,whichiswhatCstylecastsdowhenitcomestoclasshierarchies(upcasting
anddowncasting).

Whydoesthecodesilentlycompiletoawrongprogram,despitethefactthatC++alreadyforcedustoinformthecompiler
thatwehavevirtualinheritanceatthedefinitionsoftheclassesinvolvedinthecastoperation(notthedefinitionoftheJoin
classwhichisn'tnecessarilyvisibleatthecontextwherethecastoperationiscompiled)?Whydoesn'tthecompilerproduce
anerrormessageorgeneratescorrectcodeasifweuseddynamic_cast?

Theanswerissimple:inC++,thecompilercompilesrandommeaninglessthingsbecauseitcan'tbebotherednotto.

[25.14]Onemoretime:whatistheexactorderofconstructorsinamultiple
and/orvirtualinheritancesituation?
FAQ:Soandso.

FQA:Idon'twanttosummarizeit,becausewhywouldanyonewanttoknowthat?Well,exceptmaybetosuppressstupid
compilerwarningsabouttheordersofthingsininitializationlistsnotmatchingtheactualorderofconstruction.

Well,whywouldyouuseinitializationlists?

[25.15]Whatistheexactorderofdestructorsinamultipleand/orvirtual
inheritancesituation?
FAQ:Thereverseorderofconstruction.

FQA:Right.Butyouprobablyshouldn'twritecodethatdependsonthesethings.Yourcolleaguesmaygetannoyed.

HowtomixCandC++
ThesequestionsareaboutmixingCandC++,whichmaybeharderthanyou'dexpectfromthenamesofthoselanguages,
buteasierthan,say,mixingC++andC++.Staytuned.

[32.1]WhatdoIneedtoknowwhenmixingCandC++code?
[32.2]HowcanIincludeastandardCheaderfileinmyC++code?
[32.3]HowcanIincludeanonsystemCheaderfileinmyC++code?
[32.4]HowcanImodifymyownCheaderfilessoit'seasierto#includetheminC++code?
[32.5]HowcanIcallanonsystemCfunctionf(int,char,float)frommyC++code?
[32.6]HowcanIcreateaC++functionf(int,char,float)thatiscallablebymyCcode?
[32.7]WhyisthelinkergivingerrorsforC/C++functionsbeingcalledfromC++/Cfunctions?

http://yosefk.com/c++fqa/fqa.html 93/112
2/26/2015 C++ Frequently Questioned Answers
[32.8]HowcanIpassanobjectofaC++classto/fromaCfunction?
[32.9]CanmyCfunctiondirectlyaccessdatainanobjectofaC++class?
[32.10]WhydoIfeellikeI'm"furtherfromthemachine"inC++asopposedtoC?

[32.1]WhatdoIneedtoknowwhenmixingCandC++code?
FAQ:Youshouldcheckyourvendor'sdocumentation.Mostfrequentlytherulesare:

YoumustcompilemainwithyourC++compiler.
YoumustlinkeverythingwithyourC++linker.
YourCandC++compilershouldbecompatible,whichprobablymeanstheyshouldhavethesamevendorand
version.

Andyou'llneedtoreadtherestofthissectionsothatyourCfunctionscancallyourC++functionsandviceversa.

OryoucancompiletheCcodewithyourC++compileryoumayneedtochangethecode,butyoumayalsofindbugsthis
way,soit'sagoodthingtodo.Unlessyoudon'thavetheCcodeinsourceform,ofcourse.

FQA:Youhavelittlechancestosuccessfullyapplytherulesunlessyouunderstandtheunderlyingtechnicalproblemthe
rulestrytoaddress.TheproblemisinallthethingsinC++thatcannotbetranslatedtoCstraightforwardly(mostly
exceptions),andthethingswhichcanbetranslatedinseveralways(initializationofglobalvariablesbeforemainand
finalizationaftermain,manglingnamesofoverload&templatefunctions,virtualfunctioncalls,constructorprototypes,layout
ofderivedclasses,RTTIthislistisquitelarge).ManylanguageswhichareeasytomixwithChavesuchfeatures.
However,unlikeC++theyalsocomewithaformaloradefactostandarddefiningtheABI(applicationbinaryinterface)ora
sourcelevelinterfaceforCinteroperability.TheC++standarddoesn'tbother.

MostofthesethingscanonlycauseproblemswhenaparticularC++functionisexplicitlycalled.Thiskindofthingsis
addressedintherestofthequestionsinthissection.However,theglobalinitialization&finalizationsequencesarenever
explicitlycalledhencetherequirementaboutcompilingmainandlinkingtheprogramwiththeC++compiler.Astotheneed
touseCandC++compilersfromthesamevendorthisistrueintheory,butinpracticeCcompilersforagiven
hardware/OSconfigurationwillinteroperatesmoothly.SowilltheC++compilersaslongastheCsubsetofthecalling
conventionsisinvolved.However,thisrequirementisalmostalwaysamustwhenmixingC++andC++forexample,when
thirdpartylibrarieswithC++interfacesareinvolved.Thinkaboutit:mixingCandC++iseasierthanmixingC++andC++.
Isn'tthisamazing?

ThissituationisoneexcellentreasonnottofollowtheFAQ'sadvicetocompileyourCcodewithaC++compiler:Ccodeis
moreportable.ThereareotherreasonstokeepCcodeinC,suchascompilationtime,betteraccessibility(there'snoname
manglingsofunctionsbundledintoasharedlibraryareeasiertocall),etc.

[32.2]HowcanIincludeastandardCheaderfileinmyC++code?
FAQ:Likethis:#include <cstdio>,andthenstd::printf("I like std::!\n").Ifyoudon'tlikestd::,getoverit.That'sthe
waystandardnamesareaccessed.

IfyoucompileoldCcodewithaC++compiler,thefollowingwillalsowork:#include <stdio.h>,andthenprintf("No
std::!\n");allduetothemagicofnamespaces.

IfyouwanttoincludeanonstandardCheader,seethenextquestions.

FQA:Um,ifprintfandstd::printfbothwork,what'stheretogetover?printfissostandardthatthereseemstobelittle
pointinmentioningitoverandoveragain.Astothe"magicofnamespaces",thisparticularcasedoesn'treallyseemtohave
anythingtodowithit.Forsomereason,theglobalunmangledextern "C" printfisalsomadeaccessiblevianamespace std
bytheC++standard.What'ssomysteriousoramusinghere?PerhapstheFAQmeant"themagicofstandards".

IfyouwanttoincludeanonstandardCheader,basicallyyou'llhavetotweakthemthesamewayyourcompilervendor
tweakedthestandardCheaders.

[32.3]HowcanIincludeanonsystemCheaderfileinmyC++code?
FAQ:Likethis:
extern "C" {
#include "foo.h"
}

http://yosefk.com/c++fqa/fqa.html 94/112
2/26/2015 C++ Frequently Questioned Answers
Iffoo.hisyourheader,youcanchangeittomakeinclusionfromC++easier.

FQA:ThereasonyouhavetodothisisthatCfunctionnamesarenotmangledinC,there'snooverloading,soprintfis
knowntothelinkers,debuggers,etc.asprintf.ButinC++theremaybeseveralfunctionswiththesamename.Sothe
compilerhastomakeupauniquenameusinganencodingoftheargumenttypes.Forexample,theGNUCcompiler
generatesanassemblyfunctioncalled_Z6printfPKcfromC++sourcecodedefiningint printf(const char*).Different
C++compilerswilldothenamemanglingdifferentlyoneofthemanyreasonsmakingthemincompatiblewitheachother.

TheoreticallytheremaybemoredifferencesbetweenCandC++functions,andextern "C"isyourwaytotellyourC++
compiler"theseareCfunctions,dealwithallthedifferences".Inpractice,theproblemisnamemangling.Toobadthere'sno
extern "C++ compiled with a different compiler".

[32.4]HowcanImodifymyownCheaderfilessoit'seasierto#includethem
inC++code?
FAQ:Likethis:
#ifdef __cplusplus
extern "C" {
#endif
void foo();
void bar();
#ifdef __cplusplus
}
#endif

Ew,macrosareevil,washyourhandswhenyouaredone.

FQA:Togetherwiththeusual#ifndef,#define,#endiftrinity,we'vejustused7preprocessordirectivestodefineasingle
interface.Andthesesevendirectivescontainzeroinformationspecifictothatinterface.Andtheydon'thelpthecompilerto
dothingscompilersofotherlanguagescando,likelocatingtheimplementationoftheinterface.

IfyouwanttowashyourhandsaftereachpreprocessordirectiveyoutouchinC++andhavesometimelefttodoanything
elsewiththosehands,you'llhavetoworkinabathroom.

[32.5]HowcanIcallanonsystemCfunctionf(int,char,float)frommyC++
code?
FAQ:Prefixitsprototypewithextern "C"whenyoudeclareit.YoucandeclareawholebunchofCfunctionsbysurrounding
thedeclarationswithanextern "C" { ... }block.

FQA:Yeah,we'vebeenthroughthisalready.Itdoesn'tmatterwhetheradeclarationisinaheaderfileornot.NeitherCnor
C++syntaxisawareofheaderfilesorotherpreprocessorrelatedthings.Headerfilesarejustanautomatedcopypaste
mechanism.

[32.6]HowcanIcreateaC++functionf(int,char,float)thatiscallableby
myCcode?
FAQ:Prefixthedeclarationandthedefinitionwithextern "C".Youcan'thavemorethanonefCcallablefunctionsinceC
hasnooverloading.

FQA:Oh,howsimple!Andwhatifthefunctionthrowsanexception?Youdidn'tthinkyouweregoingtoescapethateasily,
didyou?

I'vejusttriedthiswiththeGNUCandC++compilers.WhenaC++functioncallsaCfunctionwhichcallsaC++function
whichthrowsanexception,youcan'tevencatchitatthefirstC++function,nottomentiondisposingtheresourcesallocated
bytheCfunction.

So,makesureyoucatchallpossibleexceptionsinyourCcallableC++functions.Bytheway,C++exceptionscanbeofany
builtinoruserdefinedtype,andyoucan'tcatchanarbitraryexceptionandcheckwhatkindofexceptionitisatruntime,
andoperator newcanthrowexceptions.Enjoy.

[32.7]WhyisthelinkergivingerrorsforC/C++functionsbeingcalledfrom
C++/Cfunctions?
http://yosefk.com/c++fqa/fqa.html 95/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:Youprobablyforgotextern "C",sothelinkerlooksforamangledC++nameinsteadofanunmangledCname.

FQA:Quiz:doesatypicalC++linkertrytocheckwhethertheunmangledCnameisdefined,andifinfactitis,askyou
somethinglike"didyouforgetextern "C"?"Hint:ifitactuallydidthissimplething,howfrequentlywouldthisquestionbe
asked?

Yousee,oneoftheadvantagesofusingC++isthatyougettoworkwithmature,industrialstrengthtoolchains.

[32.8]HowcanIpassanobjectofaC++classto/fromaCfunction?
FAQ:Youcanuseclass FredinC++(#ifdef __cplusplus),andatypedef struct Fred Fred;otherwise.Thenyoucan
defineextern "C"functionswhichacceptFred*(theFAQcontainstwoscreensofcodeillustratingthispoint,includingboth
ANSIandK&RCfunctionprototypes).

Notethatthisway,C++codewillbeabletotellwhethertwopointerstoclassobjectspointtothesameobject,andCcode
won't.That'sbecausewhenapointertoabaseclassobjectiscomparedtoapointertoaderivedclassobject,thecompiler
mayneedtodosomepointerarithmeticsbeforethecomparison.InC++,thisisdoneimplicitlywhentheexpressionp == q
iscompiled.

Notethatifyouconvertpointerstoobjectsofclassestovoid*andcomparethem,neitherCnorC++compilerswillbeable
todotherightpointeradjustments.

FQA:Pleasedon'tfollowthisadvice!ThisFAQkeepstellinghowevilthepreprocessoris,andthenitproudlypresentsthis
reallynastyscheme.Definingtypenamestomeandifferentthingsbasedonapreprocessorflagisascloseto"evil
preprocessorabuse"asitgets.Especiallywithallthesepointerequalitysubtletiesinvolved(theseareridiculousby
themselvesseriously,ifyoucanshootyourselfinthefootbysimplycomparingtwopointerstoobjects,how"object
oriented"isthelanguage?).

Here'saprettystraightforwardsolution:intheheaderfilewhichissupposedtobeusedfromC,declareastruct FredObjor
something(justuseadifferentnamethanFred,sothatpeoplecanatleastfigureoutwhateachnamemeans!Sheesh!).In
theC++implementationfile,definethestructuretoholdasinglememberaFredobject.Thisdoesn'tleadtoanyruntime
overhead.Theextrasyntaxneededfordereferencingisworththebenefitsyoucancomparepointersandhavefunin
safety.

AndifyoureallyneedtoreturnobjectsofclassesderivedfromFredjustdefineastructurewithasinglememberoftype
Fred*andnevermindthetinyruntimeoverhead.Ifyouareusingclasshierarchiestoimplementfunctionalitysosimplethat
thistinyruntimeoverheadiscomparabletotheactualworkdonebytheclasses,throwtheseclasshierarchiesawayand
stopmessingupthelivesofyourinnocentusers.

Whydothesepeoplehavetomakeeverythingcrypticanddangerous?

[32.9]CanmyCfunctiondirectlyaccessdatainanobjectofaC++class?
FAQ:Yes,iftheclasshasnovirtualfunctionsornonpublicmembers,andsodoallobjectsitcontainsbyvalue.TheFAQ
outlinesthewayinheritanceandvirtualfunctionsareimplementedatalevelallowingyoutodothepointerarithmeticsin
ordertoaccessmemberdatafromCintheseclearlyillegalcases.

FQA:"Can"maymeanmanythings:"candoitwithaparticularversionofC&C++compilers","candoitwithallcompilers
whichareactuallyoutthere","candoitwithanystandardconformingcompilers",andeven"shouldnormallydoitbecause
provisionsweremadetomakeiteasy".

TheshortansweristhatyoushouldonlydoitwiththesocalledPODtypes(whichbasicallymeans"structuresdefinedusing
Csyntax"forpeoplewhoarenotprofessionallanguagelawyers).Theonlyreasonablecaseswhenbreakingtherulesisnot
anentirelymoronicactare(1)whenyouplayaroundwiththelanguagetoseewhat'sinside,(2)whenyouhavetoretrieve
datafromclasseswithdefinitionsonlyavailableinbinaryform(youmaywanttocheckifyouractionsarelegalfirst)and(3)
youareimplementingadebuggerorthelike,inwhichcaseyou'rewritinglegitimatelynonportablecode.

Incase(2),youcouldalsoask"CanmyC++functiondirectlyaccessprivatedatainanobjectofaC++class".Mostoftenit
canifyouadda#define private publicpreprocessordirectiveatthetopofyour.cppfile.Thisworksquiteportablyand
doesnotdependonthelayoutsofC++classesinyourparticularcompiler.

PeoplewhowanttheirCcodetodirectlyaccessdataofaC++classobjectfor"speed"orsomethingprobablydon'thave
enoughrealproblems.Theartificialproblemstheycreateforthemselveswillteachthemagoodlessonprettysoon.

[32.10]WhydoIfeellikeI'm"furtherfromthemachine"inC++asopposedto
http://yosefk.com/c++fqa/fqa.html 96/112
2/26/2015 C++ Frequently Questioned Answers

C?
FAQ:Youare!C++isahighlevellanguage.InC,youcanseewhereeveryclockcycleisspentontheotherhand,inC++
youcanworkathigherlevelsofabstractionandwritemorecompactprograms.Ofcourseyoucanstillwritebadcodethe
ideaisnottopreventbadprogrammersfromdoingit,butmakeitpossibleforthereasonableonestowritesuperiorcode!

FQA:Whatisthisquestiondoinghere?PresumablypeopletrytomixCandC++,andhaveanextern "C"function
implementedinC++throwanexception,ortheinitializationstuffbeforemainnevergetscalled,ortheycomparepointersto
C++classobjectsfromCanditdoesn'twork,andtheydon'tknowwhyorhowtoevenstartfiguringitout.Therealquestion
probablyis"whydoIfeellikeI'munderneaththemachine,notjustclosetoitasopposedtoC"?

C++isnotahigherlevellanguagethanC.Thedamagecausedbylowlevelerrorsisstillnotlimited.Youstillhavetothink
aboutpointersandobjectlifecyclesandintegerendiannessandmanyotherthings.Butontopofthat,there'sahuge
amountofthingsdoneimplicitly,likeglobalinitializationanddestruction,stackunwinding,base/derivedclassespointer
adjustment,andmanymorethingsandallofthemcombinewiththelowlevelerrorsintoasingledeep,widetarpitwiththe
programmerinthemiddle.

Agoodhighlevellanguageallowsyoutoforgetaboutmanysmalldetailsofprogramexecution.Agoodlowlevellanguage
allowsyoutocontrolthemanysmalldetailsofprogramexecution.C++isnotmuchofahighlevellanguage,butit'snota
verygoodlowlevellanguageeither.

Astotheremarkabout"seeingeverycyclespentinCprograms",IreallybelievethattheFAQauthorknowsthatyoucan't
seethat,sincethat'saprettybasicfact.Youcan't"seeeverycycle"spentinassemblyprogramsinmostcasesyouhaveto
knowtheexacttargetprocessorvariantandthesystemconfigurationandazillionotherthings.TheFAQisprobablyjust
beingpoetical.

Butthere'smoretothisremarkthanfactualinaccuracyitconcentratesonamoderateproblem,failingtomentionan
arguablymoresevereone.ConsidertheC++codep = obj.getVec().begin();.Theruntimeofthiscodeisunclear
becauseitdependsonwhetherobjisavalueorareference(thelattermaybeslower)inCitwouldbemoreclear.But
there'sanotherissue:isthiscodecorrectatall?IfgetVec()returnsareferencetostd::vectorobject,maybeitiscorrect,
butifitreturnsitbyvalue,itiscertainlywrong.Thecompilerwon'tevenwarnyou,andyouwon'tnoticetheprobleminthe
codewithoutcheckingthedefinitionofgetVec.NotonlyisithardtofigureouthowmuchtimeaC++programruns,itishard
toeventellwhatitdoes,whichisnotsupposedtobetypicalofhighlevellanguages.

Pointerstomemberfunctions
ThisisbasicallyaboutthelackoffunctionobjectsandclosuresinC++.

[33.1]Isthetypeof"pointertomemberfunction"differentfrom"pointertofunction"?
[33.2]HowdoIpassapointertomemberfunctiontoasignalhandler,Xeventcallback,systemcallthatstartsa
thread/task,etc?
[33.3]WhydoIkeepgettingcompileerrors(typemismatch)whenItrytouseamemberfunctionasaninterrupt
serviceroutine?
[33.4]WhyamIhavingtroubletakingtheaddressofaC++function?
[33.5]HowcanIavoidsyntaxerrorswhencallingamemberfunctionusingapointertomemberfunction?
[33.6]HowdoIcreateanduseanarrayofpointertomemberfunction?
[33.7]CanIconvertapointertomemberfunctiontoavoid*?
[33.8]CanIconvertapointertofunctiontoavoid*?
[33.9]Ineedsomethinglikefunctionpointers,butwithmoreflexibilityand/orthreadsafetyisthereanotherway?
[33.10]Whattheheckisafunctionoid,andwhywouldIuseone?
[33.11]Canyoumakefunctionoidsfasterthannormalfunctioncalls?

[33.1]Isthetypeof"pointertomemberfunction"differentfrom"pointerto
function"?
FAQ:Itis.

Ifyouhaveanonmemberfunctionvoid f(int),then&fisoftypevoid (*)(int).

Ifyouhaveanonstaticmemberfunctionvoid C::f(int),then&C::fisoftypevoid (C::*)(int).

FQA:Ahem.::*)(linenoisecreepsin.There'smoreofitintherestofthissection.

http://yosefk.com/c++fqa/fqa.html 97/112
2/26/2015 C++ Frequently Questioned Answers
Anyway,thereasonthetypesshouldbedifferentisthatamemberfunctionacceptsahiddenparameterthis.Andthe
typesoffunctionpointersarederivedfromthetypesoftheargumentsandthereturnvalue.Obviously,theselfdocumenting
bitofsyntaxC::*saysthatthefunctiongetsathisparameteroftypeC.

[33.2]HowdoIpassapointertomemberfunctiontoasignalhandler,X
eventcallback,systemcallthatstartsathread/task,etc?
FAQ:Youdon't.Amemberfunctioncan'tbeusedwithoutanobjectoftheclass,sothewholethingcan'twork.Whatyou
candoiswriteanonmemberfunctionwrappingyourpointertomemberfunctioncall.

Forexample,threadcreationcallbacksusuallyhaveavoid*argument.Youcouldpassanobjectpointerinthatargumentto
thecallback(whichhastobeanonmember).Thecallbackwouldthencastthevoid*downtotheactualtypeandcallthe
object'smethod.

Somefunctions,likesignal,usecallbackswithoutavoid*argumentoranythingsimilar.Inthatcase,youhavenochoice
butsaveapointertotheobjectinaglobalvariable.Thecallbackcangettheobjectpointerfromthatglobalvariableandcall
themethod.

staticmemberfunctionscanbeusedinthecontextswhereaCcallbackisexpected,iftheyareextern "C".Althoughon
mostcompilersitwouldprobablyworkwithoutextern "C",thestandardsaysitdoesn'thavetowork.

FQA:ThepicturepaintedbytheFAQisn'tverypretty,buttherealitycangetevenworsethatis,morecodetowrite.For
example,youmaywanttocallanymethodofanobjecttoselectthemethodtocallatruntime,notcompiletime.That
wouldreallymeanthatyouwanttopassapointertomemberfunctionasacallback,whichiswhatthequestionisallabout.
InthescenariointheFAQ,yourproblemispassingtheobjectpointer,butthere'sactuallynopointertoamemberfunction.

Anyway,inthis"fullblown"usecase,passingjusttheobjectpointerviathevoid*argumentisnotenough.You'dhaveto
wrapthetwopointers(theobjectpointerandthefunctionpointer)inastructure,passavoid*tothatstructuretoyour
callbackandunpackthestructureinthatcallback.Simple,butquiteverbose.Prettymuchlikeimplementingfunctioncallsin
assembly.

ThisillustratesthefactthatC++isaverylowlevellanguage.WhenyouhaveaPythonobjectobjwithamethodfunc,and
youwantsomeoneexpectingacallbacktocallobj.func(),youcancreatethecallbackobjectwiththeexpressionobj.func.
Assimpleasthat.Insomehighlevellanguagesdoingthisisequallyeasyandinsomeit'smoreverbose,butnever,ever
wouldyouhavetosaveapointertoyourobjecttoaglobalvariable(andworryaboutmakingitthreadlocalwhenrelevant,
etc.).

TheproblemisthatinC++,there'snosingleconceptofa"callableobject"instead,thereareunrelatedlowlevel
mechanismsforcallingfunctions.Forexample,nonmemberfunctionpointersworkdifferentlyfrommemberfunction
pointers.Thereareubercompetentpeopleouttherewhoactuallythinktheycangetawaywithcastingvoid (C::*p)(int)to
typevoid (*)(C*,int),because,youknow,whatweneedistopassthisasthefirstparameter.Thiscanworkwithmany
compilers,untilyouneedtopassapointertoavirtualfunction.Outsmartingcompilersisusuallydumb,especiallyC++
compilers.Therereallyismorethanonefunctioncallmechanism,andthedifferentkindsoffunctionpointerarenot
convertibleyouhavetoimplementadaptersofvaryingdegreesofclumsiness.

Regardingthestaticmembersascallbacksissue:ifyourimplementationusesdifferentbinarycallingconventionsforC
functionsandC++staticmemberfunctions,callthesupportandinformthemthattheirdevelopersconsumemindaltering
chemicalsatwork.

[33.3]WhydoIkeepgettingcompileerrors(typemismatch)whenItrytouse
amemberfunctionasaninterruptserviceroutine?
FAQ:Thisisaspecialcaseofthepreviousquestion.

FQA:Itis.Sowe'llusetheopportunitytosurprise!pointoutthathandlinginterruptsinC++canbedonejustaswellas
anythingelse.Notmuchofacompliment,really,butworthnoting.

OneoftheproblemswithC++isalltheunjustifiedcriticism.Forexample,somepeoplewillscreamsomethinglike"What?!
HandlinginterruptsinC++?!"possiblyfollowedby(false)claimsaboutC++beinga"highlevellanguage"(yeah,right)and
mayberemarksaboutyourmentalhealthandstuff.Thesepeopledon'tknowwhatthey'retalkingabout,andcanmakeother
peoplebelievethatC++onlylookslikeabadthingifonedoesn'tknowwhathe'stalkingabout.

Clarifications:ofcourseyoushouldn'tthrowexceptionsininterrupthandlers,orcallnew,etc.OfcoursedoingthejobinC
wouldbebetter,butthisisn'tspecialtointerrupts.OfcoursemanyC++featurescandomoredamagewhenyouusethemto
http://yosefk.com/c++fqa/fqa.html 98/112
2/26/2015 C++ Frequently Questioned Answers
talktohardwarethanelsewhere.AllI'msayingisthatwhenyoucriticizesomething,youeitheraccompanyyourclaimswith
somereasoningoryouhavenochancetoconvincepeople(atleastnottheonesworththeeffort).

[33.4]WhyamIhavingtroubletakingtheaddressofaC++function?
FAQ:Mmmm,you'retryingtotaketheaddressinordertouseitasaCfunctionpointer,aren'tyou?Well,don'tdothat.And
don'ttrytocastyourwayoutofthis,itwon'twork.

FQA:TheFAQdidn'tansweryourquestion,didit?Instead,itassumeditknewwhatyourproblemwas,andthenanswered
adifferentquestion.Well,youcouldalsoaskyouroriginalquestionforadifferentreason.Specifically,youarealready
awareofthefactthat&C::fhasadifferenttypethan&f,butyoudon'tknowhowtospellthattype.Soyou'redoing
somethingsemanticallysensible,butyoucan'tgetthesyntaxright,becauseC++hassomuchsyntaxmakingsolittlesense.

Well,Idon'tknowthetypeof&C::feither,becauseitdependsontheargumentsIonlyknowit'ssomethinglikeT1 (C::*)
(T2,T3,T4).Sohere'sawaytofindoutthetypeofanarbitraryC++expression:

template<class T>
void show_type(const T&)
{
int eat_flaming_death[-1];
}
void test_func()
{
show_type(&C::f);
}

ThecompilerwillthensaysomethinglikeIn void show_type<TheTypeYouWantedToFigureOut>(): arrays of negative size


are not allowed.Inourcase,TheTypeYouWantedToFigureOutwillbesubstitutedwiththetypeof&C::f.

Here'sthebestpart:there'salarge"compiletimeassertions"movementpromotingaplethoraofarcanemacrosand
templateswhich,likeshow_type,willcausethecompilertofailwithanerrormessagehopefullymentioningsomethingrelated
totheproblem.ThiskindofthingisabestpracticeinC++.Isn'tlifeamazing?

[33.5]HowcanIavoidsyntaxerrorswhencallingamemberfunctionusinga
pointertomemberfunction?
FAQ:Withatypedef,makingthetypenamereadable,anda#definemacro,makingthe((obj).*(func))syntaxreadable.
Ewww,macrosareevil!

Therewerehundredsofpostingstocomp.lang.c++aboutthis,saystheFAQ.Thelayerofsyntaxproposedabovecould
savethetraffic.

FQA:TheFAQactuallyproposestousetheoldandohsoevilCmacrostocoverupthebrandnewsyntaxintroducedin
C++.TheFQAwillavoidfurthercommentsonthisadvice,sincethetargetistooeasy.

Theamazingpartaboutthehundredsofmessagesisnotthefactthatpeoplecan'tgettheC++syntaxright.Theamazing
partisthefactthatpeoplewantedtousepointerstomemberfunctions,despitethefactthattheyareprettyuseless.What
youreallyneedquitefrequentlyis"delegates"or"functors"or"closures"well,anythingthatrepresentsboththecode(a
function/anexpression/...)andthedata(anobject/boundlocalvariables/...).C++doesn'tsupportthesethingsverywell.
Perhapsthecomp.lang.c++posterstriedtoimplementsomethinglikethisontopofC++objectandmemberfunction
pointers.Maybeevensomethinggeneric,withtemplatesinheritingfromabstractbaseclassesinvolved.Yeah,thatsounds
quitelikethefavoritepasstimeofC++developers.

[33.6]HowdoIcreateanduseanarrayofpointertomemberfunction?
FAQ:First,addatypedefandamacro.Then,useFuncPtrType arr[] = {&C::f, &C::g, &C::h};

FQA:Hey,whyareweusinganevilCarray?Menotlikethis.Howabout:
std::vector<FuncPtrType> arr;
arr.push_back(&C::f);
arr.push_back(&C::g);
arr.push_back(&C::h);

There,it'smuchbetternow.Waittillyouseethefulltypenameofarrinacompilererrormessage.

[33.7]CanIconvertapointertomemberfunctiontoavoid*?
http://yosefk.com/c++fqa/fqa.html 99/112
2/26/2015 C++ Frequently Questioned Answers
FAQ:No,andifitseemstoworkonsomeplatform,itdoesn'tmakeitlegal.

FQA:ListentotheFAQ.Thisisn'tjustlanguagelawyertalkitreallyisn'tgoingtowork.Checkoutthisarticleithasalotof
materialonC++memberfunctionpointers.WARNING:thisstuffcanbeusedtoscarelittlechildren.

Thebottomlineisthatunlikeaglobalfunctionpointer,amemberfunctionpointerisnotjusttheaddressofthefirst
instructionofthefunctioninmostimplementations,apparentlywiththeexceptionofthecompilerbyDigitalMars(the
companybehindtheDlanguage).Thatcompilergenerates"thunkcode"whichhandlesthedifferencesbetweenvarious
dispatchingmechanisms(virtualvs.staticallydispatchedfunctions,differentkindsofinheritance),andusestheaddressof
thatthunkcodetorepresentmemberfunctionpointers.Quotefromthearticleaboutthisimplementation:"Whydoesn't
everyoneelsedoitthisway?"

So,really,don'tcastthesethingstovoid*youcan'tevensensiblycastthemtononmemberfunctionpointers.

[33.8]CanIconvertapointertofunctiontoavoid*?
FAQ:Stopthat.No.Anddon'ttellmeitworkedforyou.It'sillegal.

FQA:CandC++stronglyseparatebetweencodeanddata(sodomanylanguagesandhardwareprocessor
implementations).Apointertoadataobjectisnotthesameasapointertoafunction.However,inthevastmajorityof
implementationstheirsizesaregoingtobethesame,soit'spossibletoconvertafunctionpointertoavoid*,andthen
somewhereelseconvertitbackandcallthefunction.

Thisviolatesthelanguagerules.Sodoescodeassuming2'scomplementintegersandIEEEfloatingpoint.Thechanceof
bothkindsofcodetoactuallyfailonaninterestingplatformislow.Admittedly,thecodepointersarejustlikedatapointers
assumptionislessusefulthanthesignednumberscanbedividedusingrightshiftassumption,though.Sotypicallyone
wouldn'tdothiskindofcast,afterall.

[33.9]Ineedsomethinglikefunctionpointers,butwithmoreflexibilityand/or
threadsafetyisthereanotherway?
FAQ:Afunctionoidiswhatyouneed.

FQA:"Functionoid"rhymeswith"marketroid",andisatermlocaltotheFAQ,usedinsteadofthestandardterm"functor".

[33.10]Whattheheckisafunctionoid,andwhywouldIuseone?
FAQ:Itmeans"afunctiononsteroids",ofcourse.TheFAQgoesontodescribeaclasswithasinglevirtualfunctioncalled
doit.Anobjectofthisclassisbasicallyjustlikeafunctionexceptyoucanpassitargumentsinitsconstructor,anditcan
keepstatebetweencallswithoutthreadunsafeglobalvariables.Thediscussionisverylengthyanddidactic,therearelots
ofexamples.Ifyoudidn'tsaytoyourselfsomethinglike"Oh,yeah,thatproblem",youcanfollowthelinktotherealFAQ's
answertoseewhatthisisallabout.

FQA:A"functionoid"(orfunctor,asit'snormallycalled)isbasicallyamanualemulationofclosures.Closurescansaveall
thoselittleclassespeoplecreateinordertohaveafunctionpointerplussomecontext.Forexample,thefollowingcode,
whichtriestouseahigherorderfunction(for_each)inalanguagewithoutclosures(C++),iscompletelyridiculous:
struct Printer
{
std::ostream& out;
Printer(std::ostream& o) : out(o) {}
template<class T>
void operator()(const T& x) const { out<<x<<std::endl; }
};
void print_them(const std::vector<int>& them)
{
std::for_each(them.begin(), them.end(), Printer(std::cout));
}

Clearly,aforloopwouldn'tbenearlyasbad.However,ifwehadclosures,wecoulddosomethinglikethis:
void print_them(const std::vector<int>& them)
{
std::for_each(them.begin(), them.end(), lambda(x) { std::cout << x << std::endl; });
}

Thiswouldstillbeverbosebecauseofsmallerproblems(std::,mentioningthemtwice),butatleastthestupidPrinterclass
isnowreplacedwithcodegeneratedimplicitlybythecompiler.
http://yosefk.com/c++fqa/fqa.html 100/112
2/26/2015 C++ Frequently Questioned Answers
CheckoutthemonstrousboostlambdalibrarydesignedtoworkaroundthelackofclosuresinC++inadesperateattemptto
makehigherlevelfunctionsofthekinddefinedat<algorithm>notentirelyuseless.WhenItriedit,gccwouldn'tcompileit
without-ftemplate-depth=40(thedefaulttemplatenestingdepthlimit,17,isnotenoughforthislibrary),andIgot5screens
oferrormessagesfromasinglelineofcodeusingthething.Seealsothisthread,especiallythepartwheretheyexplainhow
cout << _1 << endlworksbutcout << "\t" << _1 << endldoesn't(togettherequick,searchfor"failsmiserably",then
continuetothereply).

[33.11]Canyoumakefunctionoidsfasterthannormalfunctioncalls?
FAQ:Sure!Insteadofvirtualfunctions,useinlinememberfunctionsandmakethecodeusingthe"functionoid"a
template.

FQA:Thiswaythe"functionoid"willcompileslowerthan"normalfunctioncalls"though,nottomentionthelossofflexibility
atruntime.TheruntimespeedimpactoftheobsoleteapproachtoinliningusedbyC++isdiscussedhere.Thecompiletime
speedimpactofC++templatesisdiscussedhere.Thefactthatit'syourjobtomakesurethingsareinlinedproperlyinthis
familyofscenariosisoneproblemwiththelackofclosuresinC++discussedabove.

Templates
ThispageisaboutC++templates,oneofthelargestcannonstoaimatyourfeetthattheC++arsenalhastooffer.
TemplatessolvetheproblemswithCmacrosbycreating2ordersofmagnitudemoreproblems.

[35.1]What'stheideabehindtemplates?
[35.2]What'sthesyntax/semanticsfora"classtemplate"?
[35.3]What'sthesyntax/semanticsfora"functiontemplate"?
[35.4]HowdoIexplicitlyselectwhichversionofafunctiontemplateshouldgetcalled?
[35.5]Whatisa"parameterizedtype"?
[35.6]Whatis"genericity"?
[35.7]MytemplatefunctiondoessomethingspecialwhenthetemplatetypeTisintorstd::stringhowdoIwritemy
templatesoitusesthespecialcodewhenTisoneofthosespecifictypes?
[35.8]Huh?Canyouprovideanexampleoftemplatespecializationthatdoesn'tusefooandbar?
[35.9]Butmostofthecodeinmytemplatefunctionisthesameistheresomewaytogetthebenefitsoftemplate
specializationwithoutduplicatingallthatsourcecode?
[35.10]Allthosetemplatesandtemplatespecializationsmustslowdownmyprogram,right?
[35.11]Sotemplatesareoverloading,right?
[35.12]Whycan'tIseparatethedefinitionofmytemplatesclassfromitsdeclarationandputitinsidea.cppfile?
[35.13]HowcanIavoidlinkererrorswithmytemplatefunctions?
[35.14]HowdoestheC++keywordexporthelpwithtemplatelinkererrors?
[35.15]HowcanIavoidlinkererrorswithmytemplateclasses?
[35.16]WhydoIgetlinkererrorswhenIusetemplatefriends?
[35.17]Howcananyhumanhopetounderstandtheseoverlyverbosetemplatebasederrormessages?
[35.18]WhyamIgettingerrorswhenmytemplatederivedclassusesanestedtypeitinheritsfromitstemplatebase
class?
[35.19]WhyamIgettingerrorswhenmytemplatederivedclassusesamemberitinheritsfromitstemplatebase
class?
[35.20]Canthepreviousproblemhurtmesilently?Isitpossiblethatthecompilerwillsilentlygeneratethewrong
code?

[35.1]What'stheideabehindtemplates?
FAQ:Atemplatedescribeshowtobuilddefinitions(classesorfunctions)whicharebasicallythesame.

Oneapplicationistypesafecontainerstherearemany,manymore.

FQA:Let'sgetabitmorespecific.TheFAQ'sanswerisapplicabletoCmacros,Lispmacros,MLfunctors,functionslike
evalfoundinmanyinterpretedlanguages,OScodethatgeneratesassemblyinstructionsusedtohandleinterruptsatrun
time,andjustplaincodegeneration(writingprogramsthatprintsourcecode).Thepurposeofallsuchdevicesismeta
programmingwritingcodethatworkswithcode,creatingpiecesofcodewhichare"basicallythesame"(afterall,theyare
builtfromthesamerules),andyethavesomeinterestingdifferences.Thequestionis,howdowespecifytheserulesand
thesedifferences?

TheapproachusedinC++templatesistouseintegralconstantsandtypestorepresentthedifferences,andtouseclass&
functiondefinitionstorepresenttherules.Thefirstdecisionpreventsyoufromgeneratingcodedynamically,becausethe
http://yosefk.com/c++fqa/fqa.html 101/112
2/26/2015 C++ Frequently Questioned Answers

parameterscanonlybecompiletimeentities.Theseconddecisionpreventsalmosteverythingelse,becauseyoudon'tget
touseaprogramminglanguagetogeneratecodetheonlythingyoucandoiswritecodewithsomethingsfactoredoutand
madeparameters.Youcan'tdoassimpleandusefulasetof"basicallythesame"classesasautomaticallygeneratedclass
wrappersforremoteprocedurecallsinsteadofnormal"local"functioncalls(called"proxiesandstubs"inCOMterminology
therearemanyotherterms).Evencomputingthefactorialofanintegerparameterisdoneusingsomuchcodeabusingthe
languagemechanismsthatpeoplewithnousefulworktodoareproudofbeingabletoaccomplishthis.

Beyondthosefundamentallimitations,templatesfollowthetraditionofC++featuresofinteractingpoorlywitheachother.
Templatescan'tbecompiledbecausetheyarenotcodetheyare,well,templatesfromwhichcodecanbegeneratedonce
youhavetheparameters,andthenyoucancompileit.C++,likeC,definesnowaytolocatethecompiledcodeofa
definitiongivenitsname.Consequently,templatedefinitionsareplacedin#includefiles,andrecompiledineachtranslation
uniteachtimetheyareinstantiated,eveniftheexactsameinstantiationisusedinNotherfiles.Thisproblemisamplifiedby
thetremendouscomplexityoftheC++grammar(themostcomplicatedpartofitisprobablytemplatesthemselves),making
thisrecompilationveryslow.Ifyourcodedoesn'tcompile,yougetcrypticerrormessages.Ifitdoescompile,youmight
wonderwhatitmeans.That'swheretheinteractionsoftheC++typesystem(pointers,arrays,references,constants,
literals...),function&operatoroverloadresolution,function&classtemplatespecializationselection,builtinanduser
definedimplicitconversions,argumentdependentnamelookup,namespaces,inheritance,dynamicbindingandother
thingskickin.Thesheerlengthofthislistshouldbeconvincing:neitherahumannoraprogram(say,anIDE)hasachance
againstthisunprecedentedsyntacticpower.

Poorsupportformetaprogrammingisnotnecessarilyaverybigdeal,becauseyoucandolotsandlotsofthingswithoutit.
Thatis,unlessyouworkinC++.Forexample,therearenobuiltinlistsordictionariesinC++thestandardlibraryprovides
templatesyoucanuse,soyoucanrecompilethedefinitionofeachkindofdictionaryeachtimeyouuseitinasourcefile.In
fact,mostofthecodeintheC++standardlibrarybelongstoaconceptuallyandhistoricallyseparatelibrarycalledSTL,
whichstandsfor"StandardTemplateLibrary".Forexample,that'swherestd::vector,whichtheFAQrecommendstouse
insteadoftheevilCarrays,comesfrom.

IfyouuseC++,chancesarethatyou'regoingtodealalotwithitsobscuremetaprogrammingfacilities.

[35.2]What'sthesyntax/semanticsfora"classtemplate"?
FAQ:Youaddtheparametersbeforethedefinitionofyourclass,asintemplate<typename T> class Array { ... };,and
thenyoucanusetheparametersinthedefinitionoftheclass,asinT arr[N];,andthenyoucanuseyourclassby
substitutingtheparametersasinArray<int>(theFAQgivesacodelistinginsteadofusingwordsitsexampleisassimple
asthat).

FQA:Wow,thatsoundseasy!Toobadit'swrong,intwoways.

First,thingswillnotfollowthisstraightforwardmodeltheFAQitselfdiscussesacoupleofcases,liketheneedtoresortto
thetypenamekeywordandthelookupof"nondependentnames".Allsuchcasesillustratethatyoucan'ttakethedefinitionof
aclass,parameterizesomethingsmakingitatemplate,andexpectittojustworkit'swaymoretricky.

Second,whataboutthecaseswherenobodywouldeverwritetheclassesgeneratedfromtemplatesmanually,but
templatesarestillusedbecausethat'stheonlymetaprogrammingfacilityofferedbyC++?OfcoursetherearealsoC
macros,whichhavesomelimitationstemplatesdon'thave(andviceversa),andatleastcompilefast.ButintheC++
community,macrosareconsideredthemostevilfeatureever,andusingthemistreatedasasinsomewherebetween
speedingandblasphemy.Anyway,amajorityofallusesoftemplates"beyondtypesafecontainers"actuallyfallinthis
secondcategory.Let'slookatthepreviouslymentionedcompiletimefactorialexample,whichistrivialcomparedtonifty
stuffliketypelists:
template<int N>
struct Factorial
{
enum { value = N*Factorial<N-1>::value };
};
template<>
struct Factorial<0>
{
enum { value = 1 };
};

ThiscodegeneratesN+1classesinordertocomputethefactorialofN.Talkabout"thesyntax/semanticsofclass
templates".Thisisequallydisturbingtohumansbecauseitmakessolittlesenseandtocompilers,whichinternally
representeachclassusingasizabledatastructure.Thiscompiletimecomputationtechniquetendstotakealotofcompile
time.Whenyouronlytoolisahammertemplate,notonlydoeseveryproblemlooklikeanailyoualsohammeritwith100
hammers.

Oh,andwhenyouwanttouseatemplate,bekindwiththeC++lexer(thepartofthecompilerconvertingtextto"tokens"so

http://yosefk.com/c++fqa/fqa.html 102/112
2/26/2015 C++ Frequently Questioned Answers
thattheparsercancheckwhethertheymakemeaningfulstatements).Codelikevector<vector<int>>,whichtriestodeclare
aninefficientimplementationofa2Darray,won'tcompileyouneedaspacebeforethetwo>characters.Their
concatenationlooksjustliketherightbitwiseshiftoperator.Thisisoneofthemoreharmless,albeitconfusing,awkward
interactionsbetweenC++features.

[35.3]What'sthesyntax/semanticsfora"functiontemplate"?
FAQ:Prettysimilartoclasstemplates,plusyoucanusuallyomitthetemplateparametersthecompilerwillfigurethemout
fromthefunctionarguments.Forinstance,youcanwriteaswapfunctionforswappingtwovaluesofanytype,beitintegers,
strings,setsorfilesystems(yes,theFAQactuallymentionsswappingsomeFileSystemobjects).

Bytheway,aninstantiationofa"functiontemplate"iscalled"templatefunction".

FQA:Inadditiontoalltheproblemswithclasstemplates,wearenowengagedinabattleofwitswiththeohsosmart
compilerfiguringouttemplateparametersfromfunctionarguments.Ornot.Forexample,std::max(x,5)compileswhenxis
aint,butfailstocompilewhenit'safloatorashort.Yousee,thepointoftemplatesistomake"algorithms"workwith
valuesofmanydifferenttypes,facilitating"codereuse"(thefactthatx>5?x:5islesscodethanstd::max(x,(short)5)doesn't
meanyoudon'twanttoreusecode,doesit?).

Forinstance,youcanreusestd::swaptoswapacoupleoffilesystems.AllyouhavetodoisimplementaclassFileSystem
withadefaultconstructorcreatinganewemptydiskpartition.Thecopyconstructorwillcopyallthefilesfromagiven
FileSystemtoanewlycreatedpartition,thedestructorwillwipeitout,andoperator=willdothelatterfollowedbytheformer.
Tohandleerrors,useexceptions.Youmightgetafewextradiskpartitionscreatedanddestroyed,especiallyifyoupass
FileSystemobjectsaroundtoomuchinthecode,butthat'sasmallpricetopayforreusingthe3linesofcodeinstd::swap.
Anda"commercialgrade"compilercaneveneliminatesomeofthosecopies!

Thenoteabout"functiontemplates"and"templatefunctions"isveryuseful.Toobadtherearepeopleouttherethatconfuse
thetwo.BecarefulwithC++terminology.Forexample,don'tconfuse"objectfiles"(compiledcode)with"objects"(which
belongtoaclass),whichinturnshouldn'tbeconfusedwith"instantiation"ofclasstemplates(substitutingtemplate
parametersiscalled"instantiation",theresultofthisprocessisalso"instantiation",andcreatingobjectsiscalled
"construction").Thegood(orbad)newsisthattheterminologyistheeasypart.

[35.4]HowdoIexplicitlyselectwhichversionofafunctiontemplateshould
getcalled?
FAQ:Mostofthetimeyoudon'tneedtodoitthecompilerwillguess.Itusesargumentstoguess,sowhenyourfunction
hasnone,usef<int>();.Sometimesyouwanttoforcethecompilertochooseadifferenttypethanitwouldchooseby
defaultforexample,g(45)willinstantiateg<int>,whileyouwantg<long>.Youcanforcethecompilertocallg<long>with
explicitinstantiationasing<long>(45);ortypeconversionasing(45L);.

FQA:Thereisagoodreasontoavoidallkindsof"clever"behaviorwhichgetsinyourwaywhenyoutrytofigureoutwhata
programactuallydoes(itdoesn'talwaysdowhattheauthorthoughtitwoulddo).Overloadingandtemplatespecialization
areonekindofthisbehaviorgofigurewhichfunctionisactuallycalled.Butlet'sassumeforamomentthatit'snota
problem,andthattheimportantthingistowritecodeexpressingtheauthor'sintent"clearly"inthesensethatit'snot
clutteredwith"lowlevel"detailslikewhich"version"ofafunctioniscalled.

Inthatcase,thepicturepresentedbytheFAQlooksfairyouonlyneedtoexplicitlyspecifyparameterswhenthecompiler
hasnoinformationtoguessthemitself,orwhenyoudon'tlikeitsguess.Thetruthismorecomplicated,becausesometimes
afunctionhasmorethanoneargument,andthetemplatedefinesconstraintsonthesearguments.That'swhathappenswith
std::max(x,5)whenxisafloat.Thetemplatewantstwoargumentsofthesametype,andthecompilerthinksthat"5"isof
typeint.Soeventhoughtheintentseemsclear(youprobablywant5tobetreatedasanumberofthesametypeasthatof
x),thecompilercan'tmakeadecision.Soyouhavetointerfereinthesecases,andchoosebetweentwoalmostequally
unreadablealternatives,explicitinstantiationorexplicittypeconversion.

Outofthetwooptions,explicitinstantiation,thesyntaxdefinedbyC++(asopposedtotypeconversionwhichisinherited
fromC)istypicallyworse.First,thiswaythecodeusingafunctionforcesittobeimplementedasatemplate,althoughit
doesn'treallycare,andmakesithardertogetridofthepeskytemplateswhenyoufeellikeit.Andsecond,whentheneedto
interfereanddisambiguatearisesinsideanothertemplate,youmayhavetousethefollowingsyntax,hideousevenbyC++
standards:
a.template f<long>(45);

WhileC++featuresgenerallyinteractpoorlywitheachother,templatessettherecordbyinteractingpoorlywiththemselves.

http://yosefk.com/c++fqa/fqa.html 103/112
2/26/2015 C++ Frequently Questioned Answers

[35.5]Whatisa"parameterizedtype"?
FAQ:Awaytosay"classtemplates".

FQA:Hmm,whydoweneedtwowaysofsayingthis?

[35.6]Whatis"genericity"?
FAQ:Awaytosay"classtemplates".Don'tconfusewith"generality".

FQA:Hmm,whydoweneedthreewaysofsayingthis?ApparentlyC++promotersconsidertemplatesanexcellentand
uniquefeature,despitetheirobscurityandtheavailabilityofmuchbettermetaprogrammingfacilitiesinmanylanguages.
Themanydifferentsynonymsareprobablyneededtoilluminatethekillerfeaturefrommanydifferentdirections.

[35.7]MytemplatefunctiondoessomethingspecialwhenthetemplatetypeT
isintorstd::stringhowdoIwritemytemplatesoitusesthespecialcode
whenTisoneofthosespecifictypes?
FAQ:First,makesureit'sagoodthingtodoinyourcase.Generally,itiswhenthe"observablebehavior"inthespecial
versionyouwanttoaddisidenticaltothegeneralcaseotherwise,you'renothelpingyourusers.Ifthespecialcaseis
"consistent"withthegenericcase,youcandoitasintemplate<> void foo<int>() { ... }.

FQA:"Observablebehavior"meansdifferentthingstodifferentpeople.Inparticular,manyC++userstendtoobserve
performance(ifyoudon'tcareaboutperformance,butyoustillusealanguagethatwon'tdetectruntimeviolationsof
languageruleslikeoutofboundsarrayindexes,you'reprobablywastingyourtime).

Consequently,thespecializationofvector<bool>tobespaceefficient(bystoringbitsinsteadofbytes)atthecostofspeed
(individualbitsarehardertoaccessthanwholebytes)foundinsomeSTLversionsisnotaverygoodidea,becauseit
ultimatelyconfusestheperformanceawareuser.Iftheuserwantsavectorofbits,theusercanimplementavectorofbits,
orSTLcouldsupplyone,butit'sveryinconvenientwhenyoucan'thaveasimplementalmodeldescribingwhatvectorreally
means.

Inaddition,specializationisactuallyaprettydangeroustrapbecauseitisyourresponsibilitytomakesurethatall
specializationsarevisibletothecompiler(#included)ateachpointwhereatemplateisused.Ifthat'snotthecase,youcan
gettookindsofvector<bool>instantiatedinyourprogram,triggering"undefinedbehavior"(typicallyyou'llpassavectorof
thefirstkindtoafunctioncompiledtoworkwithvectorsofthesecondkindandcrash).Sospecializingothers'templatesis
verylikelytoleadtoadisaster(becauseyoucan'tmakesurethatyourspecializationsarevisibleincodeyoudidn'twrite),
andlibrarieswhichactuallyassumethatyou'llspecializetemplatestheydefinearebestavoided.

Ifyoureallywanttousespecialization,takeintoaccountthatfunctiontemplatesdon'tsupportpartialspecialization("Iwanta
specialversionforalltypeswhicharevectorsofanyT"),onlyclasstemplatesdo(templatefunctionssupportoverloading,
whichfollowsdifferentrules).OneworkaroundistoimplementasinglefunctiontemplateworkingwithanyTanddelegate
thecalltoastaticmethodofatemplateclass,asin:
template<class T>
void f(const T& x)
{
FImpl<T>::f(x);
}

Thisway,theclassFImplcanbedefinedusingpartialspecialization.Alltheselayersofcrypticsyntaxcouldbeconsidered
tolerableiftheyultimatelyweretheonlywaytoaccomplishsomethingreallyuseful,andyoucouldforgetaboutthemonce
youweredone.Butit'sactuallyveryeasytoprogramwithoutthesecomplications,andalmostalwaysthesecomplications
getyounothingexceptforreducingmaintainability,andyougettoseethemeachtimeyouhaveacompilationerrordeep
downachainoftemplatesdelegatingtrivialworktoeachother,anddebuggingruntimeerrorsbecomesarealnightmare.

Basicallyyoucanchoosesimpleinterfacesandsimpleimplementations,orC++stylecrypticinterfacesandcryptic
implementations.It'satradeoff.

[35.8]Huh?Canyouprovideanexampleoftemplatespecializationthat
doesn'tusefooandbar?
FAQ:Forinstance,youcan"stringify"valuesofdifferenttypesusingatemplate.Thegenericversionboilsdownto

http://yosefk.com/c++fqa/fqa.html 104/112
2/26/2015 C++ Frequently Questioned Answers
ostringstream out; out << x.Butyoumightwanttodefinespecializationstohandletypeswheretheostreamoutput
operatordoesn'tdowhatyoulike(youcansettheoutputprecisionoffloatingpointnumbers,etc.)

FQA:Thismeansthatallvaluesofthesametypewillhavetobeformattedidentically.Forexample,allintegerswillbe
printedusingdecimaldigits.Ifyoupreferhexadecimal,youcandefineclass HexInt(atemplate,ofcourse,sothatitcan
handleallthedifferentintegraltypes,includinguserdefinedones).Thenyoucanusestringify(HexInt<int>(x)).You
mightneedapartialspecializationofstringifyforHexInt<T>(seepreviousFAQ).Tosavethetroubleofexplicitlypassing
thetemplateparameterstoHexInt,useacreatorfunctiontemplateHexInt<T> hexint(const T&)thecompilerwillfigureT
outfromstringify(hexint(x)).Specifyinganumberofleadingzeros(asintheformatstring"%08x")usingadvancedC++
typebasedtechniquesisleftasanexercisetothereader.

We'vedonequitesomeworkindeedinordertoprintaninteger.Timetorelaxandletthecompilerconcentratewhileit
cleverlyfiguresoutallthethingswewantittofigureout.Youusuallyprintstufffordebugging,sothelongbuildtimemaybe
annoying,butit'ssurebetterthanusingavisualdebuggerwhereyougettoseethelinenoisegeneratedfromallthoseother
templates.

Inthemeanwhile,itisquitelikelythatwhateveryourrealjobwas,someoneelse(probablysomekindofcompetitor)has
alreadydoneit.Butdidtheresultcontainamature,genericandefficientprintinginfrastructurewithreally,reallyminor
usabilityandmaintainabilityproblems?Mostcertainlyitdidn't.WhichiswhyC++templatespecializationisyourfriend.

[35.9]Butmostofthecodeinmytemplatefunctionisthesameisthere
somewaytogetthebenefitsoftemplatespecializationwithoutduplicating
allthatsourcecode?
FAQ:Youcanfactoroutthecommoncodeandonlyspecializeahelperfunctioncalledfromthecommoncode.Two
screensofsourcecodeareattachedforillustration.

FQA:Factoringoutcommoncodeandhelperfunctionsareindeedveryuseful(whichiswhyyoucandothatkindofthing
withvirtuallyeveryprogramminglanguage).TheexistenceofthisquestionintheFAQseemstoindicatethatpeopleget
unbelievablyconfusedbytemplates,andlosehopethatanythingusefultheyknowisapplicabletothem.Whichisnotthat
muchofanexaggeration.

[35.10]Allthosetemplatesandtemplatespecializationsmustslowdownmy
program,right?
FAQ:Youguessedwrong.Maybethecompilationwillbecome"slightly"slower.Butthecompilerendsupfiguringoutthe
typesofeverything,andthendoingalltheusualniftyC++optimizations.

FQA:Youguessedright.Andthecompilationwillbecomeintolerablyslow.It'snotliketheFAQislyingit'sjusttalking
aboutthestateofaffairsintheory,whereC++belongs.The"slight"slowdownofcompilationisnotevenworthdiscussing:
everythingis"slight"ifyouhavelotsoftimeonyourhands.JusttrytobuildaCprogramandamodernC++programfullof
templatesandcomparethetimeittook.Astoexecutiontime,therearepracticalproblemsmakingprogramsgeneratedfrom
templatesslowcomparedtothehandwrittenalternatives.

First,thecompilergeneratesthesamecodeoverandoveragain.Sometimesthelinkerthrowsawaytheextracopiesand
sometimesitdoesn't,andthesizeofyourprogramincreases.Inparticular,thelinkerdoesn'thaveachancetothrowaway
thefunctionswhichareidenticalattheassemblylevel,butnotatthesourcecodelevel(thinkaboutvector<int>and
vector<void*>).Itispossibletoimplementtemplatesinawayavoidingtheseproblems(byusingthesameimplementation
forallspecializationsyieldingthesameassemblycode).Itisverytediousandalmostneverdone.Twoidenticalfunctions
almostalwaystakemoretimetoexecutethanasinglefunctioncalledtwice,whichhastodowithinstructioncachesa
usefulgadgetfrequentlyoverlookedbymanypeoplewhocareabout"theoreticalefficiency"withoutactuallymeasuring
performance.

Second,whenpeopleworkwithtemplates,theyusetypestheironlyhammerforsayingalmosteverything(considerthe
HexIntclassfromthepreviousFAQ).Morespecifically,theywrapsimplevaluesofbuiltintypesinuserdefinedtypes
classes.Thetypeisusedtoselecttherightspecializationandwhatnotinfactit'susedtospecifywhattodo.Anextreme
exampleistheboostlambdalibraryitcreatesstructuresrepresentingentirefunctions,withasubstructurerepresenting
addition,asubstructurerepresentingtheconstant1,etc.

Now,"theoreticalperformancefans"maythinkthatallofthesestructuresgetoptimizedoutbytheclevercompiler.In
practice,that'salmostalwaysclosetoimpossibletodobecauseofthesocalledpointeraliasingproblem.Whenyouhavea
localvariablex,it'sclearthatnobodycanchangeitbutthecodeofthefunction,sothecompilercandolotsofthingswithx,
likestuffingitintoaregisterorevencompletelyoptimizingitout.Butonceyoupushxintoastructure,it'shardtoseewhere
http://yosefk.com/c++fqa/fqa.html 105/112
2/26/2015 C++ Frequently Questioned Answers
it'smodifiedgofigurewhohasapointertothatstructure,especiallyifyoupasstheobjecttoaseparatelycompiled
function.Sothecompilerhastoallocateamemoryslotforxandmakesurethememorycellgetsupdatedwhenxis
modifiedandthatthememorycellgetsreadwhenthere'sachancethatitcouldhavebeenchangedbysomeoneelse.Code
workingwithtemplatesandrelyingontypestodocompiletimedispatchingendsupdoinglotsofmemoryload/store
operationsatruntimesincethetypesdon'treallygoaway.

Andanyway,there'ssuchahugeamountofscenariostotakecareoftooptimizecomplicatedtemplatebasedcodewellthat
compilerwritersrarelybother.Theyareluckyiftheygettheparsingright.Eventhatisunlikelywhenyouareportingfrom
onecompilertoanother,chancesarethatmostofyourcompatibilityproblemswillcomefromthesemanticsofthecode
usingtemplates.

[35.11]Sotemplatesareoverloading,right?
FAQ:Theyareinthesensethattheyareinspectedwhenthecompilerresolvesnames(figuresouttheversionoffthat
shouldbecalledbyf(x)).Theyarenotinthesensethattherulesaredifferent.Specifically,there'stheSFINAE
(SubstitutionFailureIsNotAnError)rule:theargumenttypeshavetomatchexactlyforatemplatetobeconsideredin
overloadresolution.Iftheydon't,thecompilerwon'ttrytoapplyconversionsthewayitwouldwithafunctioninsteaditwill
discardthetemplate.

FQA:Asidefromthefactthattheacronym"SFINAE"interpretedliterallydoesn'tseemtodescribewhatit'ssupposedto
describe,thissoundsjustalittlebittooeasy.Forexample,whatdoes"exactmatch"mean?Let'shavealookatareallife
exampletakenfromtheGNUimplementationoftheC++standardlibrary.Itriedtomakethisshort,butthereareabout5
distinctstupidthingsinvolved,soitwashard.Ifyougettiredinthemiddleofthisandstop,it'sprobablyanindicationthat
youdogetthemainpointthatthingsareactuallyverycomplicatedinthisdepartmentandthatthesecomplicationsarebest
avoided.

Stupidthing#1:Onceuponatime,vector<int>::iteratorwasaplainoldtypedefforint*intheGNUSTL.Ofcoursethis
isvery,verydangerous:peoplemightusestd::vectorasifitwerejustanarrayofobjectsaseriousabstractionviolation,
youcouldgetarrestedforthatinsomejurisdictions.Atthebeginningofthe21stcentury,theguysbehindGNUSTLdecided
to"fix"thisbycreatingaclasstemplatecalled__normal_iterator.Thistemplateservesasa"stricttypedef"itwrapsany
existingiteratortype,suchasint*,anddelegatesalloperationstotheexistingtype,butcannotbeconvertedtoint*.This
hasmanyimportantbenefitsoverthepreviousimplementation,forexample,muchlongererrormessages.

Stupidthing#2:Asyoumayknow,therearetwokindsofiteratorsdefinedbySTLcontainers:iteratorandconst_iterator
becauseofinherentproblemswithconst:const iteratorisnotatallthesameasconst_iterator.IfSTLwantedtobe
consistent,itwouldalsodefinevolatile_iteratorandconst_volatile_iterator,andthennobodywouldevenlookatSTL,
whichwouldn'tnecessarilybebad.Buttheydidn't.Sonowyoualsoneedtwokindsof"normaliterators"forint*andconst
int*.

Stupidthing#3:OfcoursetheGNUSTLguysdidn'twanttodefinea__normal_const_iteratorafterall,making
conversionhardforyouisanexcellentthing,butmakingithardforthemisacompletelydifferentthing.Instead,they
decidedtosupportautomaticconversionbetweendifferentinstantiationsof__normal_iterator,byofcoursedelegating
theconversiontothewrappedtypes(templatesnormallydelegateallusefulworktosomeoneelsetheirjobisobfuscation).
Thisway,youcancompareconstandnonconstiteratorsusingthesameoperator,havingthiselegantprototype:
template<typename _IteratorL, typename _IteratorR, typename _Container>
inline bool
operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs);

Stupidthing#4:STLprovidesanother,seeminglyunrelatedservicetoitsusers.Itdefinesglobalrelationaloperatorswhich
workonargumentsofanytype.Howcantheycompareobjectswithoutknowinganythingaboutthem?Atthispointyoucan
probablyguesstheanswerofcourse,theydelegatetheworktosomeoneelse,thistimetoexistingrelationaloperators,
usinginterestingidentitiessuchas(a>b) == !(a<=b).Thisway,youcandefineonly2relationaloperators,andgettherest
"forfree".

Stupidthing#5:Exceptwhenyoucan't.Thisiswhereoursubject,overloadresolutionandtemplates,kicksin.Remember
theruleaboutonlyconsideringtemplateswhentheargumenttypesmatchtheprototypeexactly?Well,whenyoucompare
"normaliterators"ofthesametype(forexample,bothwrappingint*),thebeautifulprototypeabovematchesthearguments
"exactly".Sodothe"generic"relationaloperators.Oops,wehaveambiguousoverloading!The"solution"istodefineathird
overload,matchingthetypesevenmoreexactlybyusingasingletemplateparameter_Iteratorinsteadoftwowhichcan
possiblydiffer.Whyisthissituationconsidered"unambiguous"?Frankly,beyondthebasicintuitionsayingthatyoumust
showthecompileratypepatternassimilartoyourargumentsaspossible,Idon'tknow.That'swhyIdidn'tlisttheStupid
thing#6.Butthefirst5makemefeelthatinthiscase,ignoranceisbliss.

ApparentlythissituationlooksdiscouragingevenfrominsidetheC++universe,asindicatedbythefollowingrathersad
commentfoundinoneoftheheaderfilesoftheGNUSTL.Youcanprobablydecipherit,unlessthe5stupidthingsabove
http://yosefk.com/c++fqa/fqa.html 106/112
2/26/2015 C++ Frequently Questioned Answers
havealreadyfadedfromyourmemory:
// Note: In what follows, the left- and right-hand-side iterators are
// allowed to vary in types (conceptually in cv-qualification) so that
// comparison between cv-qualified and non-cv-qualified iterators be
// valid. However, the greedy and unfriendly operators in std::rel_ops
// will make overload resolution ambiguous (when in scope) if we don't
// provide overloads whose operands are of the same type. Can someone
// remind me what generic programming is about? -- Gaby

Thiscouldbeamusing(animplementorofthestandardlibraryofalanguagecomplainingaboutthislanguageinfiles
deliveredtousersandall)ifitweren'tsomindnumbing.PeoplewhothinktheyarebetteratC++thantheGNUSTLauthors
arewelcometowastetheirentirelifechasingand"solving"problemswithoverloadresolution,templatespecializationor
whateveritsnameis.Fortherest,tryingtoavoidtemplates&overloadingsoundslikeagoodadvice,whichcanbefollowed
toanextentevenifyouareforcedtouseC++.

[35.12]Whycan'tIseparatethedefinitionofmytemplatesclassfromits
declarationandputitinsidea.cppfile?
FAQ:"Acceptthesefacts",saystheFAQtemplatesarenotcode,justarecipeforgeneratingcodegivenparametersin
ordertocompilethiscode,itmustfirstbegenerated,whichtakesknowingboththetemplatedefinitionandthedefinitionsof
theparameterswhicharepassedtoitandthecompilerdoesn'tknowanythingaboutcodeoutsideofafilewhencompiling
thefile(whichiscalled"separatecompilation").

Soyouhavetoplacetemplatedefinitionsinheaderfiles,orelsethecompilerwon'tgetachancetoseeallthedefinitionsit
needsatthesametime.Expertsshouldcalmdownyes,it'soversimplifiedifyouknowitis,youdon'tneedthisanswer
anyway.

FQA:Therearetwoproblemswithplacingtemplatedefinitionsinheaderfileswhichmaybotheryou:yougettorecompile
themeachtimethefileisincluded,andyoudiscloseyoursourcecodetotheuser.Let'sconcentrateonthefirstproblem.
Thesecondisminoranywaybecausesourcecodeoftemplatesisn'tnecessarilyeasiertounderstandthandisassembled
objectcode.Astothefirstproblemtogetanideaaboutitsmagnitude,considerthefactthataniostreambased"hello,
world"programrequirestheGNUC++compilertoparse718K(!!)bytes.AndcontrarytotheclaimsintheFAQ,itturnsout
thattheneedtomakethesourcecodeoftemplatesavailabletothecompilerisnottheonlyreasonwehavethisproblem.

SupposeaC++compilercouldusesomerulestolocatecompileddefinitionsofclassesgiventheirnames,forexample
"std::vector<int>isalwayslocatedatthefile$OUTPUT_ROOT/templates/std/vector_int.o"andsoon.Thisway,ifyouused
vector<int>andvector<double>,you'dhavetocompilevectortwice,butifyouusedvector<int>twice,thecompilercould
avoidrecompilation.Thatwouldmakesensesinceyou'donlycompiledifferentclasseseachtimeyoucompilethetemplate.

Unfortunately,thiscan'tworkinC++.That'sbecausethecompilercan'tparsestd::vector<int>withoutparsingtheentire
preprocessedoutputgeneratedby#include <vector>.Thatparsing,whichhastobedoneoverandoveragainforeach
compiledsourcefile,takesmostofthecompilationtime.Generatingthecodeofstd::vector<int>severaltimesisthesmall
partoftheproblem,andmostcompilerwritersdon'tbothertosolveit,sinceyou'dstillhavetheparsingbottleneck.

ThebasicprobleminheritedfromCisthatthecompilercan'tlookupdefinitions.Instead,youhavetoarrange#includefiles
sothatthepreprocessorcancopyandpastedefinitionsintoasinglehugebulkcontainingeverythingrelevant(aswellas
manyirrelevantthings)forthecompilationofyoursourcefile.Cstillcompilesfastbecauseitsgrammarissimple.Many
newerlanguagesdefinenotonlytheconceptofa"class",butalsorulestohelpthecompilerlocatedefinitionsinsteadof
parsingthemoverandoveragain.C++programmersenjoytheworstofbothworlds.

[35.13]HowcanIavoidlinkererrorswithmytemplatefunctions?
FAQ:Youprobablydidn'tmakethedefinitionofatemplateavailabletoyourcompileratthepointwhereatemplateisused
(didyouimplementatemplateina.cppfile?).Therearethreesolutions:

Movethedefinitiontothe.hfile(whichmayincreasethesizeofyourcompiledcode,unlessthecompileris"smart
enough").
Addexplicitinstantiationsinyour.cppfile.Forexample,template void foo<int>();willcausethecompilerto
generatethecodeoffoo<int>,andthelinkerwillfindit.
#includethe.cppfiledefiningthetemplateatthe.cppfileusingthetemplate.Ifitfeelsweird,livewithitorreadthe
previousFAQ.

FQA:These"solutions"createnewproblems:

Movingcodeto.hfile:evenifthecodesizedoesn'tincrease,thecompilationtimewillyouaregoingtorecompile

http://yosefk.com/c++fqa/fqa.html 107/112
2/26/2015 C++ Frequently Questioned Answers
yourtemplatesfromscratcheachtimetheyareused,andtemplatesareoneofthehardestpartsofC++tocompile.
It'snicethattheFAQatleastacknowledgesthatyourcodesizemightincreasethoughinpracticeitmostcertainly
will.ToobadtheFAQdidn'tmentionitinthequestionaboutthespeedoftemplatesreplicatedcodemeansmoretime
spentinfetchingcodeintoinstructioncaches.
Explicitinstantiations:thisisonebigstepbacktoCmacros.Supposeyouhaveaparameterizedpreprocessor
macrowhichexpandstoadefinitionofacontainerclass.Onedifferencebetweenthismacroandanequivalent
templateisthatifsomeoneusesonesuchclass,thatsomeonemustalsomakesurethatthemacroisactually
expandedsomewherewiththeappropriateparametersoryoumustprovidetheseexpansions.Otherwise,therewill
belinkererrors.Withtemplates,thecompilerissupposedtogeneratetheneededinstantiationstransparentlyexcept
it'salmostimpossibletoaccomplish.Alongcomesthis"solution",movingusbacktosquareone.
Includingthedefinitionatthepointofusage:thissharestheproblemsofthefirsttwooptions.Ifyouusetemplates
in.hfiles,youmayhavetoincludethe.cppfilesdefiningtheminthese.hfiles,gettingtheproblemsofoption1.But
thebenefitofoption1transparencyisgone:quitesimilarlytooption2,itisnowyourjobtomakethedefinitionofa
templateavailablewhereverthetemplateisused.

[35.14]HowdoestheC++keywordexporthelpwithtemplatelinkererrors?
FAQ:It's"designed"toeliminatetheneedtomakethedefinitionofatemplateavailabletothecompileratthepointof
usage.Currently,there'sonlyonecompilersupportingit.Thekeyword'sfutureis"unknown".

Anadviceforfuturisticprogrammersfollows.Itshowsawaytomakecodecompatiblewithbothcompilersthatsupport
exportandthosethatdon'tusingguesswhat?thewondersoftheevilCpreprocessor.Amongotherthings,theFAQ
advisesto#define exportundercertainconditions.

FQA:"Howdoesithelp",isthatwhatyouwanttoknow?OKthen.Theexportkeywordhelpswithtemplatelinkererrorsjust
thewayasongaboutpeacehelpstostopabulletpenetratingafoot.Ithelpsjustlikeakeywordfindbugstellingthecompiler
tofindandreportallthebugsinapieceofcodewouldhelpyouwithbugs.

TherestofC++makesthiskeywordimpossibletosupportinanyusefulwaythatwouldactuallyyieldfastercompilation
comparedtothecasewhentemplatedefinitionsareincludedatheaderfiles.That'swhymostcompilersdon'tbotherto
supportit,andthat'swhythefutureofthekeywordis"unknown":it'suseless.

IfyouspotsomeonefollowingtheFAQ'sadvice(#ifdef EXTRATERRESTRIAL_COMPILERandallthat),callanambulance.
Warning:thepatienthaslikelyreachedaveryagitatedstateandmightescapebeforethepeoplequalifiedtodealwiththe
situationarrive.Trytooccupythepatient'smindwithadiscussionaboutthefactthat#definingkeywordsisillegalC++.
Proposetoconsultyourlawyer.Tryto"design"acoupleofkeywordstogether(lookupsynonymsinadictionary,imagine
themprintedinpopularfonts,stufflikethat).Improvise.It'sgonnabeoversoon.

[35.15]HowcanIavoidlinkererrorswithmytemplateclasses?
FAQ:It'sjustlikeerrorswithtemplatefunctions,whichwereexplainedinthepreviousanswers.

FQA:Yep,it'saboutthesame.

[35.16]WhydoIgetlinkererrorswhenIusetemplatefriends?
FAQ:IfyouhaveaclasstemplateCdeclaringafriendlikeFoo<T> f(),thecompilerassumesthatthere'saglobalfunction
f()returningFoo<T>.Youprobablymeantadifferentthing,namelythere'safunctiontemplatetemplate<class T> Foo<T>
f(),andyouwantitsinstantiationf<T>()tobeafriendofyourinstantiationC<T>.

Therearetwowaysaroundthis:

Declarethefunctiontemplatebeforethedefinitionoftheclass,andadd<>tothefrienddeclaration,asinfriend
Foo<T> f<>();
Definethefriendfunctiontemplateinsidethebodyoftheclass.

FQA:InbothsolutionsthesyntaxisunrelatedtothesemanticstoanextentremarkableevenforC++.

Whydoes<>meanthatwearetalkingaboutaninstantiationofatemplatefunction?Whynotuseakeyword(like,justan
exampleoffthetopofthehead,thetemplatekeyword)tosaythat?!TheC++wayisuncompromisinglyugly,especiallyin
theexamplementionedbytheFAQitself:operator<< <>(...).

Andevenwhenyoudon'thaveaproblemwithplacingthedefinitioninaheaderfile,theseeminglycleanersecondwayis
actuallymorecryptic.ThisbreaksoneoftheveryfewthingsinC++youcannormallycounton:thatadeclarationofa

http://yosefk.com/c++fqa/fqa.html 108/112
2/26/2015 C++ Frequently Questioned Answers
functionoratypelooksjustlikeadefinitionwithoutthebody.Here,wechangethemeaningoftheprototypebyaddinga
body:insteadofdeclaringafunction,wenowdeclaredanddefinedafunctiontemplate.

Lastbutnotleast,theveryfactthatthisproblemexistsisanindicationofareadabilityproblemwiththeC++grammar.How
manypeoplewouldguessthattheoriginaldeclarationreferstoafunctionandnotafunctiontemplate?

Howisonesupposedtonavigatethroughthisswampofarbitrarysyntax?Ofcourseoneshouldn'texpectthekindof
readabilityyougetwithanaturallanguagefromaprogramminglanguage.Ofcourseanyformallanguagewillbehave
"counterintuitively"attimes.Butpeopledodealwithformallanguagesquitesuccessfully,whenitispossibletokeepa
reasonablycompactmodelofthekeyrulesinone'smind.Inthesecases,evenifyoubumpintoabehaviorwhichdoesn't
makesenseatthefirstglance,youcanthinkagainand"Ofcourse,ofcourse,Iknowwhatit'sdoing!".Doyoufeelthatyou
understandwhataC++compilerisactuallydoing?NeitherdomostC++usersoutthere.

[35.17]Howcananyhumanhopetounderstandtheseoverlyverbose
templatebasederrormessages?
FAQ:There'sa"freetool"convertingcompilererrormessagestomorehumanreadableones.Itworkswithmanycompilers.

Anexamplefollows,havingasnippet[STL Decryptor: Suppressed 1 more STL standard header message]init.

FQA:Ohreally?Any"templatebased"errormessages?Hmm,whydidn'tthecompilerwritersproducecleanerror
messagesinthefirstplaceifasingletoolcancleanupallthemesscreatedbymanydifferentcompilers?Thesepeople
mustbequitelazyand/orstupid.Orarethey?

Actually,no,theyarenot.Theerrormessagesarecrypticbecausetemplatesarecryptic,andmostcompilerscan'treallydo
muchbetterthantheydotoday.

Thetoolmentioned(withoutthename)andlinkedtobytheFAQiscalledSTLFilt.That'swhytheFAQdoesn'tmentionthe
name.That'swhyitsoutputdoesmentionSTL.That'swhyitworksatallyoucan'timprovegenerictemplateerror
messages,butyoucanfilterSTLrelatedmessagesifyouknowhowSTLisimplementedineachspecificcase.

Weneedacouplemoretools,likeSTLCompilationTimeReducerandSTLDebugInformationBeautifier,andwe'reallset.Yet
anotherproofthatgenericmetaprogrammingfacilitiesareabetterwaytoimplementcontainersthanbuildthemintoa
language.

Ifyouwishtoimplementatemplatelibrary,don'tforgettoimplementatoolfilteringtheerrormessagesyouruserswillget,
aswellastheothercooltools,foralltheflavorsofcompilersoutthere.

[35.18]WhyamIgettingerrorswhenmytemplatederivedclassusesa
nestedtypeitinheritsfromitstemplatebaseclass?
FAQ:Thiscanhurt,sitdown.Thecompilerdoesn'tlookfor"nondependent"names(onesthatdon'tmentionthetemplate
parameters)in"dependent"baseclasses.SoifyouinheritedanestedclassortypedefAfromyourbaseclassB<T>,youcan
onlyaccessitusingadependentname,likeB<T>::A,butyoucan'tuseanondependentname,likeplainA.

Andyou'llhavetoprefixthat"dependent"namewiththetypenamekeyword.That'sbecausethecompilerdoesn'tknowthat
B<T>::Aisatype(thinkabouttwospecializations,onedefininganestedclassAandonedefiningaglobalvariableA).

FQA:ThisillustratestwogenericproblemswiththeC++grammar.

First,classtemplatesarenotjustparameterizedclassdefinitions,becausethecrazyC++namelookupgetscrazierwhen
youareinsideatemplate.Sodon'tassumeyoucantakeaC++classdefinition,factoroutabunchofparametersandgeta
workingtemplatedefinition.

Second,tellingaC++typenamefromaC++object/functionnameisinsanelycomplicated.Thisinteractsbadlywith
templates,constructors,andeverythingelse.

AstothepossiblereactionsofuserstheFAQattemptstoanticipate:whilerunningawaymaybejustified,sittingdownis
probablynot.Gooddeveloperstendtotesttheircode,soevenifthecompilerdidn'tspitanerrormessageanddidthewrong
thingsilently(forinstance,usedatypecalledAfromtheglobalnamespace),atestwillfindtheerror.Stupidcompiler
behavioronlyfeelslikepainforpeoplewhothinkthattheextremelyslowC++compilersspendtheirtimeinfindingalltheir
bugs,anddon'tbothertotesttheresult.ThosepeopleshouldrelaxandsavetheirtearsfortheC++runtimeerrors.

[35.19]WhyamIgettingerrorswhenmytemplatederivedclassusesa
http://yosefk.com/c++fqa/fqa.html 109/112
2/26/2015 C++ Frequently Questioned Answers

memberitinheritsfromitstemplatebaseclass?
FAQ:ThereasonsareidenticaltothoseinthepreviousFAQ.Buttheworkaroundsaredifferentconvertf()tothis->f()
oraddthestatementusing B<T>::f()toyourclassdefinition.Usingthefullyqualifiednamelikeitwasdoneintheprevious
FAQ(B<T>::f())willalsowork,exceptwhenthefunctionisvirtual,inwhichcasethecompilerwillusestaticbinding,not
dynamicbinding.

FQA:Yep,thecasewithmemberfunctionsissimilartothecasewithnestedtypes,withtheadditionalbonusofinteracting
badlywithvirtualfunctions.

TheFAQhasahilariouscommentinthespiritof"thisdoesn'tmeanthattemplateinheritancedoesn'tworkbutthename
lookupworksdifferently".Andthat'sC++foryou:it'snotlikeyoucan'twritecode,it'sjustthatyoucan'ttellforsurewhat
anyparticularnameorsomeotherpartofitmeans.

[35.20]Canthepreviousproblemhurtmesilently?Isitpossiblethatthe
compilerwillsilentlygeneratethewrongcode?
FAQ:Yesthecompilermightcallafunctionoruseatypefromtheglobalnamespaceinsteadofwhatyoumeant,for
example.

FQA:It'snotashorriblethatalanguagecansilentlymisinterpretwhatyoumeanasitmaysound.Anylanguagewilldothis
tothecreativebutimprecisehumanmind(formallanguagesaside,peoplefrequentlymisunderstandeachother).

Withformallanguages,youcanformarelativelysimplemodelwhichwillhelpyouunderstandtheseproblems.It'sthesame
withC++exceptforthe"simple"part,soC++andyouwillmisunderstandeachotherprettyfrequently.

Andyoucanalsotestyourcodebycreatingprogramsthatcheckifitdoeswhatyouwantittodoinabunchofcases.It'sthe
samewithC++exceptthatitcompilesforeverandyouhavetowritenotableamountsofcodetoimplementthesimplesttest,
soC++codeendsupbeingtestedprettyrarely.

FQAerrors
Thispageliststhefactualerrors/inaccuraciesintheC++FQA.Ifyoufindone,pleasesendmeemail.Ifyouareright,I'll
publishyourcorrection,eithergivingyouthecreditoranonymously,accordingtoyourchoice.

By"factualerrors",Imeanstatementswhichcanbeprovedwrongorrefutedbyapracticallyfeasibletest.

Positiveexamples:ifIsaythatC++compilersmaygenerateslowercodefromCsourcethanCcompilersunlessexception
supportisoff,andinfactnocommerciallysignificantcompilerdoesthat,I'mwrong(don'tbotherwiththisoneIalready
checkedit).IfIsaythattheC++grammarisundecidable,andyouformallyproveit'sdecidable,I'mwrong(advice:don't
botherwiththisone,too).

Negativeexamples:ifIsaytemplatesaremostlyapplicabletocontainers,andyouknowmanyotherwaystousetemplates,
it'sreallyaqualitativeargument.Youcallthis"uses",Icallit"abuses".It'slikearguingwhethersedisapplicabletonumerical
computing:it'samatterofcommonsense,andwe'llgetnowherethere'snoformaldefinitionofaTuringtarpit.Ifyouinform
methatI'm"inconsistent"because"sometimesmyproblemwithC++isthatit'stoolowlevelforhighlevelworkand
sometimesIthinkit'stoohighlevelforlowlevelwork",themessagewilllandinthebitbucket,too.Ithinkthatdoingboth
lowlevelandhighlevelworkinC++issuboptimal(Itriedboth)youarefreetocallit"inconsistency".Ifyouthinkthefact
thatC++isa"superset"ofCmeansthatC++can'tbeinferiortoC,govisitChernobylandbuyyourselfaradioactivecatwith
7legsandawing(codenamed"cat++"),butdon'texpectmetoagree.

Sometimesbaseclassconstructorsmusthaveinformationontheactualobjecttype
C++hasbool,abuiltintypenotinC
#define private publicisnotenoughtocancelC++encapsulation
ThespecialcasewhenNdimensionalarrayscanbeallocateddynamicallywithnew
Conversionsbetweencodeanddatapointersarecommon

Sometimesbaseclassconstructorsmusthaveinformationontheactual
objecttype
EugeneToder:TheFQAansweraboutthedispatchingofvirtualfunctionsinconstructorsisbasedonthefollowing
statement:Base::Basedoesn'tknowthatit'scalledinordertoultimatelyinitializeaDerivedobject.Thisiswrong,since
http://yosefk.com/c++fqa/fqa.html 110/112
2/26/2015 C++ Frequently Questioned Answers
virtualinheritancecan'tworkthatway.Inparticular,AFAIK,cfront,thefirstC++compiler,alwayspassedconstructorsa
parametertellingwhetheritinitializesabaseclassobjectoraderivedclassobject,nomatterwhatkindofinheritancewas
involved.

Yossi:Thisisanerrorbyitself,andit'salsoinconsistentwithotherinformationintheFQA.Specifically,theFQAmentions
(followingtheFAQ)thatwithvirtualinheritance,theprogrammermustdirectlyinitializevirtualbaseclassobjectsinthe
derivedclasses,eveniftheyarenotits"immediate"baseclasses(thatis,itinheritsthemindirectly).Butwhatifsomeone
derivesanotherclass,Derived2,fromaclassDerivedwithvirtualbaseclasses?It'sstilluptotheprogrammertoinitializethe
virtualbaseclassobjectsinDerived2butDerivedalreadycontainscodethatdoesthis(andmaybeotherbaseclasses
containsuchcode,whichisourprobleminthefirstplace).Sowedon'twanttousethevirtualbaseclassinitializationcode
inDerived,butwedowanttousetheotherinitializationcodeinDerived.Therefore,theconstructorofDerivedmustknow
whetheritultimatelyinitializesaDerivedobjectoranobjectofsomechildclass,suchasDerived2,inordertoconditionally
executesomeoftheinitializationcode(ortheconstructorcodemustbegeneratedtwice,whichisthesameinthiscontext).

IthinkthattheFQAanswerstillhasitsvalueinthesensethatitmayactuallybemoreintuitivetoC++programmers.That's
becausetheFAQanswerbasicallysays,"C++preventsyoufromapotential(notcertain)errorofaccessinguninitialized
membersofaderivedclass,bysilentlydoingsomethingdifferentthanwhatyouthoughtitwould".Thisisaveryspecialfact
whichhastobememorizednormallyC++doesn'ttrytopreventaccesstouninitializeddata.TheFQAanswersays,"C++
doesthethingnaturallyandefficientlyfollowingfromtheunderlyingimplementation:tosetupvptrtopointtothecorrect
vtable,you'dhavetospendcycles(atinyamountofthem,butC++isfrequentlyveryconservativeaboutruntimecost)".
Arguably,thisismoreconsistentwiththerestofC++andiseasiertoremember.Butofcourseitdoesn'tmakethe
erroneousstatementintheFQAcorrect.

C++hasbool,abuiltintypenotinC
FromaUsenetposting(incomp.lang.c++.moderated):Yousaid"C++doesn'taddanybuiltintypestoC."Whataboutbool?

Yossi:Thisstatementisfalse(wait,that'snotgood,Imeantheonequotedintheposting).TheFQAdoesmentionthatC++
addsbuiltintypeswhichareessentiallynewkindsofpointers(references,pointerstomembers),butitdoesn'tsaythisin
DefectiveC++wherethefalseassertionappears,anditfailstomentionboolinthiscontextanywhere.

Unlikethepreviousitem,thiserrordoesn'tinvalidatethereasoninginthetextwhereitappears.Specifically,thecontextof
theerroneousstatementisthediscussionofhighlevelbuiltintypes,whichdon'tmapdirectlytoCtypesthewaybooldoes,
primarilybecausetheirsizesarenotknownatcompiletime.

#define private publicisnotenoughtocancelC++encapsulation

AsAndreasKreypointedout,you'dalsoneed#define protected publicand#define class struct.Thelatterwillfailto


workwithcodeliketemplate<class T> class X {...},becausethekeywordstructcannotbeusedintemplateparameter
lists.Theremaybeotherproblemsrelatedtointeractionsbetweenaccesscontrolandnamelookup.

AnotherthingIfailedtomentionintheoriginalcontext:re#definingkeywordsisn'tlegalC++.Itwillonlyworkin
implementationswherepreprocessingisaseparatepass,whichisunawareofthekeywordsandtreatsthemasidentifiers.
I'veneverworkedwithanimplementationdoingitdifferently,but#define private publicisstillillegalC++.It'sonlyuseful
fordebugging(toprintprivatedatawithoutchangingheaderfilesandrecompilingforhours),andtoillustratethatC++
encapsulationisuselessforsecurity(thelatterwasmyoriginalpoint).

ThespecialcasewhenNdimensionalarrayscanbeallocateddynamically
withnew
Whenallarraydimensionsexceptforthefirstareknownatcompiletime,youcanallocatearraysdynamicallywithnew.
That'sbecauseC++arraysareflatsequencesofobjectsofthesametype.Inourcase,thoseobjectsare(N1)dimensional
arrays.IfanyofthoseN1dimensionsweren'tknownatcompiletime,the(N1)dimensionalarraywouldn'tbepossibleto
describewithaC++type.Butnotknowingthefirstdimensionuntilruntimedoesn'tcreatethisproblem.

JoeZbiciakfoundthatanswer16.16failstomentionthis.Answer16.20does,but16.16isstillincorrectbecauseitsaysyou
onlyhave2waystoallocateNdimensionalarraysdynamically.However,inourspecialcase,youhaveathirdway.

Conversionsbetweencodeanddatapointersarecommon
TheFQAsaysthatconversionsbetweenfunctionpointersandvoidpointersarerare(independentlyofbeingillegal,though
supportedonmanymachines).PatrickWaltoncounters:

http://yosefk.com/c++fqa/fqa.html 111/112
2/26/2015 C++ Frequently Questioned Answers
"Actually,thisisdoneallthetimefordynamiclinking,indlsymonPOSIXplatforms(returnsavoid*,evenforcodepointers)
andGetProcAddressonWindows(returnsavoid (*)(),evenfordatapointers).Interestingthatbothplatformsviolatethe
standardinoppositeways.InthecaseofPOSIX,there'salotofpaininvolvedinmakingthisrequiredinterfaceworkon
systemswherefunctionpointersarelongerthandatapointers."

IwonderwhyneitherWindowsnorPOSIXdefinedtwofunctions,onereturningavoid*andonereturningavoid (*)().

Copyright20072009YossiKreinin
revised 17 October 2009

http://yosefk.com/c++fqa/fqa.html 112/112

Das könnte Ihnen auch gefallen