C++ Coding Techniques: A Collection of Techniques For Writing C++ Code

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 48

C++CodingTechniques

AcollectionoftechniquesforwritingC++code

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Outlineforthesession
Buildinglargesystems
Whyonearthdowebother?

ProgrammingGuidelines
Gettingyourcodeorganized

C++CodingIdioms
Provenrecepies

C++Gotcha's
Mistakesalreadymadebyothers

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Goalswhenbuildinglargesystems
Thesystemshouldpromote: Reusability Extensibility Flexibility

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Reusability
Thesystemshouldconsistofcomponentsthatcanbe reused. Reusabilityisnecessaryto:
reducethedevelopmenttime(longterm) improvereliabilityofthesystem

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Extensibility
Extensibilityisnecessaryto: Supportextensionstotheoriginalsystem Supportadditionofnewfeatures

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Flexibility
Thesystemshouldnotberigid
Achangeinonecomponentshouldnotnecessitatechangesinother components

Note:
Dependenciesarenotnecessarilyexplicit Problemsnotcaughtbycompiler Problemsnotcaughtbytesting

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Abstractioniseverything!
Encapsulationhidestheinternalimplementationofa component Interfacesareusedtoprovidemethodsforuserstoworkwith thecomponent Inheritanceisusedtospecializeanabstraction

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Encapsulation
ThemostimportantconceptinOOP
Noencapsuling...noobjectorientation

Hidestheinternalsofacomponent Providesanabstractinterfaceforcomponentusers
Alloperationsarethroughtheinterface

Allowtheimplementationtochange
Norequirementoncomponentuserstochangetheircode

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

Encapsuling:example classWriter{ public: ... voidwrite(inti); voidwrite(floatf); voidwrite(constchar*c_str); ... private: ... };
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 9

Encapsuling:exampleofusage classPoint{ public: voidwrite(Writer*writer)const{ writer>write(x); writer>write(y); } private: intx,y; };


Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 10

Encapsulingissues
Encapsulinggoals:
Maintaintheobjectinaconsistentstate Separateimplementationandabstraction Allowimplementationtochange

Definemethodsfortheabstraction Donotdefinemethodsfortheimplementation
Iwilldemonstratesomeexamplesinafewslides

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

11

Encapsulingissues,contd.
Donotexposetheinternalstate
Keepprivatepartstoyourself! Donotexposeinternalseventhroughaccessorfunctions Makeusersrelyonimplementation Mayallowusersto(accidentally)changeinternalstate:
Impossibletomaintainconsistentency Herebedragons!

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

12

Encapsuling:example
classWriter{ Writer represents public: how data is written ... voidwrite(inti); WriteBuf represents voidwrite(floatf); where data is voidwrite(constchar*c_str); written ... private: WriteBufm_buf; };

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

13

Encapsuling:advantagesofthiscode
Interfacecompletelyhidesinternalimplementation
WriteBufandWritercanhascompletelydifferentinterfaces

Implementationcanbechangedfreely
Withoutaffectingtheinterface Hencewithoutchanginganycodethatusestheinterface

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

14

Exposinginternals:examples
Expr::lhs()andExpr::rhs()
Methodnotdefinedfortheabstraction Whatiftheexpressionisunary?

Table::get_cache() and Table::clear_cache()


Cachenotpartoftheabstraction
Notaclearcutcase:dependingondefinition

Objectuserswillrelyonitsexistance Whatifyouwantto(re)moveit?

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

15

Adigressionintomutable
classExpr{ Exprrepresentsan intcompute()const{ expression if(cache.invalid()) cache.set(...); Holdacachetoavoidre returncache.val(); computations } private: ... Cachecache; };

Cacherepresentsavalue cache CacheisinsideExprclass

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

16

Adigressionintomutability
ConsideranExprclasswithacacheinsideandconsiderthe followingcode:
inteval(constExpr&expr){ returnexpr.compute(); }
$g++Wallansipedanticmutable.ccomutable mutable.cc:Infunction'inteval(constExpr&)': mutable.cc:33:error:nomatchingfunctionforcallto 'Expr::compute()const' mutable.cc:21:note:candidatesare:intExpr::compute()<near match>

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

17

Adigressionintomutability
Value eval(constExpr&e) { returne.compute(); }

Instanceeisconst Cacheinsidetheobject? Fieldsinsideconstobjectsare immutable Codewillnotcompile Usemutable

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

18

Adigressionintomutable
classExpr{ Cacheornocacheisan intcompute()const{ implementationissue if(cache.invalid()) cache.set(...); Implementationissues returncache.val(); shouldnotbevisibleinthe } private: ... mutableCachecache; };

interface Hence:usemutable

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

19

Interfaces:what'sitreallyabout?
Hidingtheinternalsofacomponent Policiesforoperatingonanabstraction Welldesignedintefacespromote:
Reusabilitybyabstractingtheimplementation Flexibilitybyisolatingindependentpartsfromeachother Robustnessbynotallowinguncontrolledchangestotheinternals

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

20

InterfaceDesignGuidelines
Interfacesshouldbedesignedfromtheperspectiveofthe caller
Interfacesarecalledmanytimes,butimplementedjustafew

Documentbeforeimplementation
Writeusescases! Themorethebetter Nodistractionfromimplementationissues

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

21

UsecaseDrivenDesign
Promotescompleteinterfaces
Bywritingusecasesyouputyourselfintheroleoftheinterfaceuser

Spotlimitationsintheinterface Encouragesminimalisticinterfaces
Discouragescreationofmonolithicinterfaces

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

22

Inheritance
Specializationofanclass Implementanabstraction
Aspecialformofspecialization

Strategicextensibility
Possibletoextendthesystemaccordingtothepoliciessetbythe designer Herepoliciesarerepresentedasclasseswithvirtualfunctions

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

23

Inheritance

Writer

writeTo

WriteBuf

FileWriteBuf

StringWriteBuf

SocketWriteBuf

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

24

Inheritance:example
Awritebufferthatdatacanbewrittento Dataiswrittenasablockofbytes Ifthebufferisinabadstate,nodatawillbewritten

classWriteBuf{ public: virtualsize_twrite(void*buf,size_tsz)=0; virtualboolis_good()const=0; };

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

25

Inheritance:example
classFileWriteBuf:publicWriteBuf{ FILE*m_file;//isprivatebydefault public: FileWriteBuf(char*name) :m_file(fopen(name,a+)){} size_twrite(void*buf,size_tsize){ if(m_file) returnfwrite(buf,1,size,m_file); return0; } boolis_good()const{returnm_file!=0;} };
TheWorldsMostPopularOpenSourceDatabase

Copyright2005MySQLAB

26

C++ProgrammingTechniques

AsmrgsbordofvariousC++codingtechniquesand guidelines

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

27

Trustthecompiler
Thecompilerisyourfriend.Trustthecompiler.
Trust...butverify Checkassembleroutputifnecessary

Compilersgoodatstraightforwardcode
Useconstants Avoiddarkcornersofthestandard

Easytounderstandmeanseasytooptimize

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

28

Clevercoding:anexample

ucharfoo_1(ulonga) { return!!(a<<11); }
movl8(%ebp),%eax popl%ebp sall$11,%eax testl%eax,%eax setne%al movzbl%al,%eax ret
Copyright2005MySQLAB

ucharfoo_2(ulonga){ if(a&0x1FFFFF) return1; return0; }


testl$2097151,8(%ebp) popl%ebp setne%al ret

TheWorldsMostPopularOpenSourceDatabase

29

Nogratuitouswritestomemory
Writingtomemorycost
Busspeedvs.CPUspeed

Branchescost Writepipelinefriendlycode Recomputevalue?

Writecachefriendlycode Globalvariablescost Localvariablesarecheap

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

30

Gratuitouswritestomemory:example
Functioncomp()doesnot touchmemory Firstversionforcesglobal variabletobewrittento memorybeforecall variableintoautovariable andwritesbackafter computation
intfunc_g(){ g_var+=comp(g_var); g_var+=comp(g_var); g_var+=comp(g_var); returng_var; } Memoryaccesses:10to13 intl_var=g_var; l_var+=comp(l_var); l_var+=comp(l_var); l_var+=comp(l_var); return(g_var=l_var); } Memoryaccesses:5
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 31

Secondversionloadsglobal intfunc_l(){

Includefilehandling
Alwaysuseincludeguards! Nevereverallowanycircularincludes!
Includeguardsdonotprotectagainstcirculardependencies Checkthisonaregularbasis Symptom:weirderrormessagesaboutincompleteorundefined structuresand/orclasses

Organizemoduleas:
Headerfileholdingbasic(nonclass)definitions Headerfileholdingclassdefinitions Codefileholdingimplementations

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

32

Modulestructure
#ifndefFOO_H_INCLUDED #defineFOO_H_INCLUDED #include<cstdlib> classFoo{...}; ... #endif #includefoo.h #include<cstdlib> Foo::Foo(){...} ...
Copyright2005MySQLAB

Headerfile
Includeguard Includewhatisused Forwarddeclareclasses

Sourcefile
Moduleheaderfilefirst Includewhatisused Standardheaderfileslast
TheWorldsMostPopularOpenSourceDatabase 33

RAIIIdiom:Resourceallocationisinitialization
Resourcesareaquiredonconstruction Resourcesarereleasedondestruction
Instanceisdestroyedautomaticallywhenleavingscope Noriskofforgettingtoreleaseresource

Example:
boolpacket(Writer&out,constchar*str,intval) { Writer::Mutexmutex(out); out.write(str); out.write(val); returnout.is_good(); }
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 34

Writingtwoitemsthatshouldbewrittenatomically.

TheLawoftheBigThree
Ifaclassdefinesacopyconstructor,acopyassignment operator,oradestructor,itprobablyneedstodefineall three. Allthreemanipulateownershipoftheresourcesusedbyan object Ifsomeoperationisnotallowed,makethefunctionprivate
Declarationissufficient,nodefinitionnecessary

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

35

Missing:CopyConstructor
classString{ public: String(constchar*c_str) :m_str(newchar[strlen(c_str)]){...} ~String(){delete[]m_str;} private: constchar*m_str; }; Stringmake_string(){ Stringb(Helloworld); returnb; }
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 36

Missing:assignmentoperator
classString{ public: ... String(constString&that) :m_str(newchar[strlen(that.str)]){...} private: constchar*m_str; }; Stringmake_string(){ Stringa(Hello); Stringb; b=a; returnb; }
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 37

Assignmentoperator:standardidiom
classString{ public: ... String&operator=(constString&that){ Stringcopy(that); swap(copy); return*this; } voidswap(String&str){ std::swap(m_str,str.m_str); } ... };

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

38

Assignmentoperator:idiomvariations
//Slightlyterserversionofthepreviousone String&String::operator(constString&that){ String(that).swap(*this); return*this; } //Moreoptimizerfriendly String&String::operator=(Stringthat){ swap(that); return*this; }

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

39

Accessibilityvs.visibility
classMyClass{ private: voidstore(inti){...} public: char * voidstore(doublef){...} }; voidfoo(){ MyClassc; NULL c.store(0); }
error: 'void Cell::store(int)' is private

error: within this context

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

40

Virtualfunctionhandling
Virtualfunctionsshouldbeprivate
Occationallyprotected,butneverpublic

Why?
Separateinterfacefromimplementation Virtualfunctionsarepartofimplementation Implementationdetailsshouldbehidden Hence,virtualfunctionsshouldbeprivate

Note:
Privatefunctionscanbeoverridden

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

41

VirtualFunctionUsage:example
classBase{ public: voidtweak(){ do_tweak(); } private: virtualvoiddo_tweak()=0; }; classDerived:publicBase{ private: virtualvoiddo_tweak(){ std::cout<<HelloWorld!<<std::endl; } };
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 42

Gotcha's

Somepiecesofcodethatdoesnotworkasyouprobably expect

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

43

#1:ConstructorCalling
Callingvirtualfunctionsfrom classA{ constructorsordestructors Objectdoesn'texistuntil afterconstructorcompletes Notanimplementation issue!
Languagedesignissue

public: A(){init();} private: virtualinit(); }; classB:publicA{ ... private: virtualinit(){...} };

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

44

#2:ArraysofObjects
classA{...}; classB:publicA{...intx;}; voidfoo(Aa[]){...a[i]...}; voidbar(){ Bb[20]; foo(b);//?!?!? }

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

45

#3:Initializationor...what?
classString{ public: String(constchar*str){...} }; classConcat:publicExpr{ public: Concat(constString&a, constString&b){...} Stringvalue()const{...} };
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 46

#3:Initializationor...what?
intconcat(char*a,char*b){ Concatstr(String(a),String(b)); returnstr.value(); } error:requestformember 'value'in'str',whichisof nonclasstype'Concat() (String,String)'
Ifsomethinglookslikeadeclaration,itis Paranthesesareallowedaroundparameternames strisdeclaredasfunctionacceptingtwoString(instances) andreturningaConcat(instance)
Copyright2005MySQLAB TheWorldsMostPopularOpenSourceDatabase 47

Recommendedreading
GuruoftheWeekbyHerbSutter http://www.gotw.ca/ ExceptionalC++StylebyHerbSutter ModernC++ProgrammingbyAndreiAlexandrescu C++Templates:TheCompleteGuidebyDavid VandevoordeandNicolaiM.Josuttis
Notforthefainthearted

Copyright2005MySQLAB

TheWorldsMostPopularOpenSourceDatabase

48

You might also like