Documente Academic
Documente Profesional
Documente Cultură
1.Soluţiitemplate2.Funcţiitemplate3. Clasetemplate4.
Parametriifuncţiilorşiclaselortemplate5.Tratareaelementelortemplate6.Soluţiitemplate
pentruimplementareacolecţiilorde dateCAP. 7
CAP. 7
7.1. Soluţiitemplate
ObiectiveleprincipaleurmăriteînlimbajulC++aufostgenericitateaşireutilizareacodului.Aceste obiective au
fost atinseprin introducerea a două mecanisme: Mecanismul moştenirii, care permite extinderea
funcţionalităţii claselor existente şi reutilizarea codului compilat; Mecanismul “template”, care permite
reutilizarea codului sursă.
CAP. 7
7.1. Soluţiitemplate
Mecanismul “template” nu a făcut parte din forma iniţială a limbajului C++, fiind introdus de abia în
1990; în momentul actual, acest mecanism face parte din propunerea de standardizare a limbajului C++.
CAP. 7
7.1. Soluţiitemplate
Considerentulprincipalcareaconduslaapariţiasoluţiilor“template”afostimposibilitateadeareutilizacodulpe
ntrumoduleaicăroralgoritmiaufostimplementaţi,datoritătipurilordeparametricarediferădelaoimplementa
relaalta.Caexemplu,deşialgoritmulpentruofuncţiedeordonareesteacelaşi,codulsursătrebuierescris(“adap
tat”)pentrufuncţiacareordoneazăîntregi,pentrufuncţiacareordoneazăalfabeticnumeleunorpersoanesaup
entrufuncţiacareordoneazăpersoaneledupăvârstaacestora.
8
CAP. 7
7.1. Soluţiitemplate
Înideeadeaobţineuncodsursăcâtmaigeneral,limbajulvineînsprijinulprogramatorului,oferindu-
iposibilitateadeadefinifuncţiişiclase(tipuri)generice(engl.“template”).Mecanismul“template”poatefiaplic
atatâtfuncţiilor(algoritmilor),câtşiclaselor(tipurilordedate).
Template-
urile(şabloanele)permitdefinireaunorfamiliideclase(tipuri)saufuncţiigenerice,încaretipurilededateasupra
căroraseopereazăsuntspecificatecaargumente.
CAP. 7
7.1. Soluţiitemplate
unde:lista_argumenteconţine unul sau mai multe argumente formale, separate prin virgulă, fiecare
definit prin tipul argumentului şi numele lui, iar declaratietrebuie să declare sau să definească o funcţie
sau o clasă.
10
CAP. 7
7.1. Soluţiitemplate
Argumenteleformale:-
detippredefinitdinlistadeargumenteseintroducprinnumeletipuluiurmatdenumeleargumentului,-
detipdefinitdeutilizator(clase)seintroducprinspecificatorulclassurmatdenumeleargumentului.De
exemplu, o declaraţie de template poate arăta în felul următor:
X şi Y sunt argumente de tip (clasă) şablon (template), iar s este argument întreg.
11
1.Soluţiitemplate2.Funcţiitemplate3. Clasetemplate4.
Parametriifuncţiilorşiclaselortemplate5.Tratareaelementelortemplate6.Soluţiitemplate
pentruimplementareacolecţiilorde dateCAP. 7
12
CAP. 7
7.2. Funcţiitemplate
Funcţiile template sunt asemănătoare expresiilor macro, utilizând diferiţi parametri. Pentru a înţelege
despre ce este vorba, să considerăm exemplulcare îşi propune să implementeze o funcţie generică
(template) de comparare a două numere întregi, a două numere reale, adouă obiecte de tip cercşi a
două obiecte de tip dreptunghi. Funcţia va primi ca argumente referinţe către datele de comparat şi o va
returna pe cea mai mare dintre ele.
13
CAP. 7
7.2. Funcţiitemplate
Deşi algoritmul implementat este acelaşi, funcţia trebuie rescrisă pentru fiecare tip de parametri cu care
trebuie să lucreze. Exerciţiul7.1.:
14
CAP. 7
7.2. Funcţiitemplate
15
CAP. 7
7.2. Funcţiitemplate
16
CAP. 7
7.2. Funcţiitemplate
Este mult mai avantajos şi mai natural să scriem o singură funcţie generică (template), care să fie
specializată pentru fiecare tip de parametri. Pentru realizarea automată a acestui lucru, compilatorul
trebuie informat că definiţia funcţiei este “outline”; informarea compilatorului se realizează prin
specificaţiile template.
17
CAP. 7
7.2. Funcţiitemplate
Funcţiatemplate vafi:template <class Obiect> Obiect mai_mare_dintre(Obiect& x1, Obiect& x2) {if
(x1>x2) return x1; else return x2; }
18
CAP. 7
7.2. Funcţiitemplate
Prefixul template <class Obiect> specifică declararea unui template (clasă, tip) cu un argument cu
numele Obiect. După această introducere, Obiect este folosit exact la fel ca orice tip de date, în tot
domeniul clasei template declarate. Cum “lucrează” compilatorul? Întâlnirea cuvântului cheie template,
semnalează prezenţa unei funcţiisau a unei clase template.Compilatorul suspendă procesul normal
folosit pentru generarea secvenţelor de instrucţiuni. După citirea definiţiei, îşi construieşte o
reprezentare internă a modelului generic.
19
CAP. 7
7.2. Funcţiitemplate
20
CAP. 7
7.2. Funcţiitemplate
21
CAP. 7
7.2. Funcţiitemplate
//. . . . . . . double a1, a2; cin>>a1>>a2; cout<<mai_mare_dintre(a1, a2); //versiuneacu paramde tip
double inti1, i2; cin>>i1>>i2; cout<<mai_mare_dintre(i1, i2); //versiuneacu paramde tip int}
Dupăoverificareprealabilăacoduluisursă(pentrudepistareaeventualelorfuncţiisautipuritemplate),laîntâlni
rea(apelul)uneifuncţiitemplate,compilatorulgenereazăodeclaraţieaversiuniispecializateafuncţieipentruti
pulparticulardedatecareaparecaargument.
22
CAP. 7
7.2. Funcţiitemplate
23
1.Soluţiitemplate2.Funcţiitemplate3. Clasetemplate4.
Parametriifuncţiilorşiclaselortemplate5.Tratareaelementelortemplate6.Soluţiitemplate
pentruimplementareacolecţiilorde dateCAP. 7
24
CAP. 7
7.3. Clasetemplate
25
CAP. 7
7.3. Clasetemplate
Unele limbaje (de exemplu, Pascal), au tablouri mărginite. Un programator poate defini un astfel de
tablou specificând atât marginea inferioară, cât şi cea superioară pentru indexul de acces al tabloului. De
exemplu, dacă la declararea unui astfel de tablou se specifică limitele 5 şi 9 (indexul va trebui să se afle
în intervalul [5,9]), încercarea de a accesa elementul de indice 20, va genera o eroare (ulterior, la fiecare
accesare a elementelor tabloului se verifică dacă elementele cerute există).
26
CAP. 7
7.3. Clasetemplate
O astfel de structură este uşor de manevrat folosind o clasă template (Array). Definim un template care
este parametrizat de tipul elementului care urmează a fi reţinut de vector. Ulterior putem avea tablouri
de caractere, de întregi sau de orice altă structură definită de utilizator.
27
CAP. 7
7.3. Clasetemplate
Declarareaclaseitemplate(caşiîncazulfuncţieitemplate)
începecucuvântulcheietemplate,urmatdetipulparametrizat,specificatîntre<>.
28
CAP. 7
7.3. Clasetemplate
29
1.Soluţiitemplate2.Funcţiitemplate3. Clasetemplate4.
Parametriifuncţiilorşiclaselortemplate5.Tratareaelementelortemplate6.Soluţiitemplate
pentruimplementareacolecţiilorde dateCAP. 7
30
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
31
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
Parametriipot fi: tipuride date (predefinite, definite de utilizator); constante. Parametri tipuri de date
sunt furnizate prin numele lor, prefixat de cuvântul cheie class.Orice parametru care nu are drept prefix
cuvântul class este considerat, în mod automat, constantă.
32
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
Exemplu:
template<classT>template<intDim_Vect,intDim_Elem>template<classtip_Elem,longDim,classComparato
r>ObservămcăparametriiT,tip_Elem,Comparatorsuntdetipurinecunoscute(generice),urmândcaacestetipu
risăfieinstanţiateulterior.Tipulnuestespecificatexplicit,devenind,elînsuşi,unparametru.Caşiîncazulfuncţiil
orgenerice,pentruclaseletemplate,acesteapotfiinstanţiate,oriundeestenecesarăprecizareaunuitipdedată.
33
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
//1 Stack <int> istack; // generareauneistivede intregiStack <float> fstack; // generarea unei stive de
reali Stack <char> fstack; // generareauneistivede caractere//2 typedefStack <float> Stack_float;
Stack_floatfstack;
34
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
Observaţie:
Tipurile concrete cu care sunt substituite tipurile generice ale funcţiilor şi claselor template, pot fi tipuri
predefinite sau tipuri definte de utilizator. Dintre tipurile predefinite, pot face parte şi pointerii către
funcţii, ca în exemplul:Exemplu:
35
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
În situaţiile în care o clasă conţine un atribut de tip altă clasă template, această clasă trebuie să fie şi ea
declarată template, dupa cum ilustrează exemplul:Exemplu:
template <class T1, class T2> class CClass{ T1 t1; T2 t2; ... }; template <class T1, class T2> class
MyClass{ CClass<T1,T2> myAttrib; ... };
36
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
S-ar putea ca în unele cazuri, în clasa în care folosim o clasă template, să nu avem nevoie de toate
tipurile generice ale acelei clase. Atunci, acele tipuri care vor fi nefolosite vor fi declarate void.Exemplu:
template <class T1, class T2> class CClass{ T1 t1; T2 t2; ... }; template <class T> class
MyClass{ CClass<void,T> myAttrib; ... };
37
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
Parametri funcţiilor şi claselor template, pot fi şi constante.Se implementează clasa Tablou, în care
dimensiunea maximă a tabloului este parametru (constant) al clasei template. Exerciţiu:
template <class T, intcMax> class Tablou{ private: T *tablou; intmaxElem; public: Tablou() :
maxElem(cMax) { tablou= new T[cMax]; } ~Tablou() { delete []tablou; } T& operator[] (intindex) { return
tablou[index]; } void AfiseazaTablou(); };
38
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
template <class T> void Tablou<T>::AfiseazaTablou() { for(int i = 0; i< maxElem; i++) cout<< tablou[i] << "
"; cout<< endl; } main() { Tablou<float, 5> t1; Tablou<char, 10> t2; Tablou<int, 20> t3; Tablou<char, 10>
t22; t1[0] = 12.35; t2[1] = 35.12; t2[0] = 'i'; t3[0] = 3; t1.AfiseazaTablou(); }
39
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
40
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
41
CAP. 7
7.4. Parametriifuncţiilorşiclaselortemplate
RESTRICŢII LA TRANSMITEREA PARAMETRILOR // 2 template <class T> voidg1(T t1, T t2) { ... } main()
{ g1(1,1); // corect: T1 si T2 de tip int. g1(12.34, 56); // eroare: T1 de tip double, T1 de tip int!!! }
42
1.Soluţiitemplate2.Funcţiitemplate3. Clasetemplate4.
Parametriifuncţiilorşiclaselortemplate5.Tratareaelementelortemplate6.Soluţiitemplate
pentruimplementareacolecţiilorde dateCAP. 7
43
CAP. 7
7.5. Tratareaelementelortemplate
Una dintre problemele pe care le implică utilizarea elementelor template este poziţia codului
corespunzător acestora.Aşa cum s-a subliniat anterior, ca şi în cazul funcţiilor inline, pentru elementele
template, codul iniţial este “expandat”. Observaţia principală este că mecanismul de instanţiere a
funcţiilor templateeste valabil doar în situaţia în carecodul sursă este organizat într-un singur
fişier(clasele şi funcţiile template).
44
CAP. 7
7.5. Tratareaelementelortemplate
45
CAP. 7
7.5. Tratareaelementelortemplate
#pragma <nume_directiva>
În cazul în care compilatorul nu recunoaşte directiva, o ignoră, negenerând eroare sau atenţionare.
46
CAP. 7
7.5. Tratareaelementelortemplate
Prezenţa acesteia determină lansarea compilatorului, cu aceste opţiuni. Această directivă se introduce în
codul sursă.
47
CAP. 7
7.5. Tratareaelementelortemplate
Deşi elementele template sunt tratate de către compilatoare şi linkeditoare în mod diferit, există două
metode de bază: Metoda template smart, prin care întregul cod ataşat unei clase template (declaraţii,
definţii ale elementelor template şi a membrilor statici) se plasează în header; căutarea duplicatelor
rămâne în seama compilatorului. Metoda template manual, prin care declaraţiile elementelor template
se plasează în header, iar implementarea –într-un fişier separat.
48
CAP. 7
7.5. Tratareaelementelortemplate
În cazul metodei template smart, compilatorul iniţializează elementele template în funcţie de necesităţi
şi asigură existenţa unei singure copii a fiecărei iniţializări în momentul linkeditării (în cazul includerii
multiple a aceluiaşi fişier header). De exemplu, pentru mediul Borland C++, metoda poate fi specificată
în două moduri: Prinopţiuneade compilare–Jg; Prin opţiunea “Smart Template“ (opţiune implicită) din
meniul “C++ options”.
49
CAP. 7
7.5. Tratareaelementelortemplate
În cazul metodei template manual, prin “pragma option”, se specifică următoarele opţiuni ale
compilatorului: Opţiunea –Jgd, care anunţă compilatorul că urmează o definire publică a instanţierilor
unor elemente template (dde la define);
Opţiunea -Jgx atenţionează asupra caracterului extern al declaraţiilor instanţierilor de tip template (xde
la extern).
50
CAP. 7
7.5. Tratareaelementelortemplate
51
CAP. 7
7.5. Tratareaelementelortemplate
52
CAP. 7
7.5. Tratareaelementelortemplate
53
CAP. 7
7.5. Tratareaelementelortemplate
54
1.Soluţiitemplate2.Funcţiitemplate3. Clasetemplate4.
Parametriifuncţiilorşiclaselortemplate5.Tratareaelementelortemplate6.Soluţiitemplate
pentruimplementareacolecţiilorde dateCAP. 7
55
CAP. 7
Una din modalităţile cele mai frecvent utilizate de creare a colecţiilor sigure ca tip (type-safe) pentru
obiecte de orice tip de date, este prin utilizarea claselor template. Clasa sau clasele care descriu forma
colecţiei (vector, listă, etc.) se definesc ca şi clase template, având ca argument tipul de date din care se
vor crea colecţiile respective. La declararea unei colecţii pentru un tip dat ca argument, compilatorul
creează colecţia de forma dată de clasa template pentru tipul de date primit ca argument. Nu se folosesc
conversii explicite de pointeri, astfel încât aceste clase de colecţii sunt sigure ca tip.
56
CAP. 7
Se obţin astfel colecţiile parametrizate. Exemple de astfel de colecţii sunt colecţiile de tip şir (vector,
listă, stivă, coadă) sau colecţii de tip mulţime (Set, Map). Diferenţierea este dată de
implementare:•implementarea unui vector cu liste sau cu masive; •implementarea unui şir asociativ
(map) cu tabele de dispersie sau cu arbori), •pentruregăsirea elementelor se utilizează iteratorii.
57
CAP. 7
şi defineşte diverse tipuri de colecţii şi iteratorii ataşaţi. Exemple de tipuri parametrizate din
STLsunt:Vector(şir unidimensional de elemente de tip T), List(listă dublu înlănţuită de elemente de tip T),
Queue(coadă de elemente de tip T), Dequeue(coadă cu 2 capete de elemente de tip T), Stack(stivă de
elemente de tip T), Map(şir asociativ de elemente de tip T), Set(mulţime neordonată de elemente de tip
T), Bitset(şiruri de biţi).
58
SFARSITUL Capitolului7
PROGRAMAREACALCULATOARELORŞILIMBAJEDE PROGRAMAREII
Programareacalculatoarelorşilimbajede programareII