[31.1] How can I make a perl-like associative array in C++?
Use the standard class template map!ey"#al$% &incl'de strin($ &incl'de map$ &incl'de iostream$ 'sin( namespace std) main*+ , mapstrin("int"lessstrin($ $ a(e) -- a(e is a map .rom strin( to int a(e[/0red/] 1 23) -- 0red is 23 years old a(e[/4arney/] 1 35) -- 4arney is 35 i. *todayIs0reds4irthday*++ -- 6n 0red7s 8irthday" ++ a(e[/0red/]) -- increment 0red7s a(e co't /0red is / a(e[/0red/] / years old9n/) : 1111111111111111111111111111111111111111111111 111111111111 [31.3] How can I build a <a!orite container" o ob#ects o di$erent t%pes& ;o' can7t" 8't yo' can .ake it pretty well. In C-C++ all arrays are homo(eneo's *i.e." the elements are all the same type+. However" with an e<tra layer o. indirection yo' can (ive the appearance o. a hetero(eneo's container *a hetero(eneo's container is a container where the contained o8=ects are o. di>erent types+. T'ere are two cases wit' 'etero(eneous containers. ?he @rst case occ'rs when all o8=ects yo' want to store in a container are p'8licly derived .rom a common 8ase class. ;o' can then declare-de@ne yo'r container to hold pointers to the 8ase class. ;o' indirectly store a derived class o8=ect in a container 8y storin( the o8=ect7s address as an element in the container. ;o' can then access o8=ects in the container indirectly thro'(h the pointers *en=oyin( polymorphic 8ehavior+. I. yo' need to know the e<act type o. the o8=ect in the container yo' can 'se dynamicAcast$ or typeid*+. ;o'7ll pro8a8ly need the #irt'al Constr'ctor Idiom[3B.C] to copy a container o. disparate o8=ect types. ?he downside o. this approach is that it makes memory mana(ement a little more pro8lematic *who /owns/ the pointed-to o8=ects? i. yo' delete these pointed- to o8=ects when yo' destroy the container" how can yo' ('arantee that no one else has a copy o. one o. these pointers? i. yo' don7t delete these pointed-to o8=ects when yo' destroy the container" how can yo' 8e s're that someone else will event'ally do the deletein(?+. It also makes copyin( the container more comple< *may act'ally 8reak the container7s copyin( .'nctions since yo' don7t want to copy the pointers" at least not when the container /owns/ the pointed-to o8=ects+. ?he second case occ'rs when the o8=ect types are dis=oint -- they do not share a common 8ase class. ?he approach here is to 'se a handle class. ?he container is a container o. handle o8=ects *8y val'e or 8y pointer" yo'r choice) 8y val'e is easier+. Dach handle o8=ect knows how to /hold on to/ *i.e. "maintain a pointer to+ one o. the o8=ects yo' want to p't in the container. ;o' can 'se either a sin(le handle class with several di>erent types o. pointers as instance data" or a hierarchy o. handle classes that shadow the vario's types yo' wish to contain *reE'ires the container 8e o. handle 8ase class pointers+. ?he downside o. this approach is that it opens 'p the handle class*es+ to maintenance every time yo' chan(e the set o. types that can 8e contained. ?he 8ene@t is that yo' can 'se the handle class*es+ to encaps'late most o. the '(liness o. memory mana(ement and o8=ect li.etime. ?h's 'sin( handle o8=ects may 8e 8ene@cial even in the @rst case. 1111111111111111111111111111111111111111111111 111111111111 [31.3] How can I insert-access-chan(e elements .rom a linked list-hashta8le-etc? I7ll 'se an /insertin( into a linked list/ as a prototypical e<ample. It7s easy to allow insertion at the head and tail o. the list" 8't limitin( o'rselves to these wo'ld prod'ce a li8rary that is too weak *a weak li8rary is almost worse than no li8rary+. ?his answer will 8e a lot to swallow .or novice C++7ers" so I7ll (ive a co'ple o. options. ?he @rst option is easiest) the second and third are 8etter. 1. Dmpower the Fist with a /c'rrent location"/ and mem8er .'nctions s'ch as advance*+" 8ack'p*+" atDnd*+" at4e(in*+" (etC'rrDlem*+" setC'rrDlem*Dlem+" insertDlem*Dlem+" and removeDlem*+. Gltho'(h this works in small e<amples" the notion o. a c'rrent position makes it di>ic'lt to access elements at two or more positions within the list *e.(." /.or all pairs <"y do the .ollowin(.../+. 3. Hemove the a8ove mem8er .'nctions .rom Fist itsel." and move them to a separate class" FistIosition. FistIosition wo'ld act as a /c'rrent position/ within a list. ?his allows m'ltiple positions within the same list. FistIosition wo'ld 8e a .riend[12] o. class Fist" so Fist can hide its innards .rom the o'tside world *else the innards o. Fist wo'ld have to 8e p'8liciJed via p'8lic mem8er .'nctions in Fist+. Kote% FistIosition can 'se operator overloadin( .or thin(s like advance*+ and 8ack'p*+" since operator overloadin( is syntactic s'(ar .or normal mem8er .'nctions. 3. Consider the entire iteration as an atomic event" and create a class template to em8odies this event. ?his enhances per.ormance 8y allowin( the p'8lic access mem8er .'nctions *which may 8e virt'al [3B] .'nctions+ to 8e avoided d'rin( the inner loop. Un.ort'nately yo' (et e<tra o8=ect code in the application" since templates (ain speed 8y d'plicatin( code. 0or more" see [!oeni(" /?emplates as inter.aces"/ L66I" 2" C *Mept N1+]" and [ Mtro'str'p" /?he C++ Iro(rammin( Fan('a(e Mecond Ddition"/ 'nder /Comparator/]. 1111111111111111111111111111111111111111111111 111111111111 [31.2] )'at*s t'e idea be'ind templates& G template is a cookie-c'tter that speci@es how to c't cookies that all look pretty m'ch the same *altho'(h the cookies can 8e made o. vario's kinds o. do'(h" they7ll all have the same 8asic shape+. In the same way" a class template is a cookie c'tter .or a description o. how to 8'ild a .amily o. classes that all look 8asically the same" and a .'nction template descri8es how to 8'ild a .amily o. similar lookin( .'nctions. Class templates are o.ten 'sed to 8'ild type sa.e containers *altho'(h this only scratches the s'r.ace .or how they can 8e 'sed+. 1111111111111111111111111111111111111111111111 111111111111 [31.C] Ohat7s the synta< - semantics .or a /.'nction template/? Consider this .'nction that swaps its two inte(er ar('ments% void swap*intP <" intP y+ , int tmp 1 <) < 1 y) y 1 tmp) : I. we also had to swap Qoats" lon(s" Mtrin(s" Mets" and 0ile Mystems" we7d (et pretty tired o. codin( lines that look almost identical e<cept .or the type. Rindless repetition is an ideal =o8 .or a comp'ter" hence a .'nction template% templateclass ?$ void swap*?P <" ?P y+ , ? tmp 1 <) < 1 y) y 1 tmp) : Dvery time we 'sed swap*+ with a (iven pair o. types" the compiler will (o to the a8ove de@nition and will create yet another /template .'nction/ as an instantiation o. the a8ove. D.(." main*+ , int i"=) -S...S- swap*i"=+) -- Instantiates a swap .or int Qoat a"8) -S...S- swap*a"8+) -- Instantiates a swap .or Qoat char c"d) -S...S- swap*c"d+) -- Instantiates a swap .or char Mtrin( s"t) -S...S- swap*s"t+) -- Instantiates a swap .or Mtrin( : Kote% G /template .'nction/ is the instantiation o. a /.'nction template/. 1111111111111111111111111111111111111111111111 11111111111 [31.T] Ohat7s the synta< - semantics .or a /class template/? Consider a container class Grray that acts like an array o. inte(ers% -- ?his wo'ld (o into a header @le s'ch as /Grray.h/ class Grray , p'8lic% Grray*int len11B+ % lenA*len+" dataA*new int[len]+ , : UGrray*+ , delete [] dataA) : int len*+ const , ret'rn lenA) : const intP operator[]*int i+ const , ret'rn dataA[check*i+]) : intP operator[]*int i+ , ret'rn dataA[check*i+]) : Grray*const GrrayP+) GrrayP operator1 *const GrrayP+) private% int lenA) intS dataA) int check*int i+ const , i. *i B VV i $1 lenA+ throw 4o'nds#iol*/Grray/" i" lenA+) ret'rn i) : :) L'st as with swap*+ a8ove" repeatin( the a8ove over and over .or Grray o. Qoat" o. char" o. Mtrin(" o. Grray-o.-Mtrin(" etc" will 8ecome tedio's. -- ?his wo'ld (o into a header @le s'ch as /Grray.h/ templateclass ?$ class Grray , p'8lic% Grray*int len11B+ % lenA*len+" dataA*new ?[len]+ , : UGrray*+ , delete [] dataA) : int len*+ const , ret'rn lenA) : const ?P operator[]*int i+ const , ret'rn dataA[check*i+]) : ?P operator[]*int i+ , ret'rn dataA[check*i+]) : Grray*const Grray?$P+) Grray?$P operator1 *const Grray?$P+) private% int lenA) ?S dataA) int check*int i+ const , i. *i B VV i $1 lenA+ throw 4o'nds#iol*/Grray/" i" lenA+) ret'rn i) : :) Unlike template .'nctions" template classes *instantiations o. class templates+ need to 8e e<plicit a8o't the parameters over which they are instantiatin(% main*+ , Grrayint$ ai) GrrayQoat$ a.) GrraycharS$ ac) GrrayMtrin($ as) Grray Grrayint$ $ aai) : Kote the space 8etween the two $7s in the last e<ample. Oitho't this space" the compiler wo'ld see a $$ *ri(ht-shi.t+ token instead o. two $7s. 1111111111111111111111111111111111111111111111 111111111111 [31.5] Ohat is a /parameteriJed type/? Gnother way to say" /class templates./ G parameteriJed type is a type that is parameteriJed over another type or some val'e. Fistint$ is a type *Fist+ parameteriJed over another type *int+. 1111111111111111111111111111111111111111111111 111111111111 [31.W] Ohat is /(enericity/? ;et another way to say" /class templates./ Kot to 8e con.'sed with /(enerality/ *which ='st means avoidin( sol'tions which are overly speci@c+" /(enericity/ means class templates. 1111111111111111111111111111111111111111111111 111111111111
Learn Python Programming for Beginners: Best Step-by-Step Guide for Coding with Python, Great for Kids and Adults. Includes Practical Exercises on Data Analysis, Machine Learning and More.