Professional Documents
Culture Documents
C++ Coding Techniques: A Collection of Techniques For Writing C++ Code
C++ Coding Techniques: A Collection of Techniques For Writing C++ Code
C++ Coding Techniques: A Collection of Techniques For Writing C++ Code
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
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?
Objectuserswillrelyonitsexistance Whatifyouwantto(re)moveit?
Copyright2005MySQLAB
TheWorldsMostPopularOpenSourceDatabase
15
Adigressionintomutable
classExpr{ Exprrepresentsan intcompute()const{ expression if(cache.invalid()) cache.set(...); Holdacachetoavoidre returncache.val(); computations } private: ... Cachecache; };
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(); }
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
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
TheWorldsMostPopularOpenSourceDatabase
29
Nogratuitouswritestomemory
Writingtomemorycost
Busspeedvs.CPUspeed
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
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
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