LECTOR ADRIAN RUNCEANU
Programare orientată pe obiecte
Universitatea “Constantin Brâncuşi” din Târgu-Jiu
Facultatea de Inginerie
Departamentul de Automatică, Energie şi Mediu
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
2
Curs 9 Funcții şi clase Template
(Şabloane)
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
4
1. Funcții template
Prin funcții template înțelegem funcții model, șablon.
Aceste tipuri de funcții se utilizează deoarece, de multe ori în programare se aplică același algoritm de rezolvare pentru anumite probleme în care doar tipurile de date utilizate diferă.
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
5
Astfel pentru fiecare tip de date ar trebui scris câte o funcție.
În loc să facem acest lucru construim o funcție template pe care o putem utiliza ulterior pentru orice tip de date.
Astfel funcția va primi un parametru formal care poate avea un nume, de exemplu T.
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
6
O funcție template se poate defini
astfel:
Functii Template (Sabloane)
template <class T> tip_functie
nume_functie (lista parametri
formali)
{
…..
}
template <class T> tip_functie
nume_functie (lista parametri
formali)
{
…..
}
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
7
Parametrii formali pot fi de tipul formal T
Tipul funcției poate fi de tipul formal T
Apelul unei funcții template cu un singur tip
formal se face utilizând un tip efectiv, adică
tipul care va fi folosit în locul tipului formal
T:
Functii Template (Sabloane)
nume_functie<tip_efectiv>
(lista parametri efectivi)
nume_functie<tip_efectiv>
(lista parametri efectivi)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
8
Programul de mai jos definește o funcție template care returnează valoarea maximă dintre două variabile:
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
9
Exemplu 1: #include<iostream.h> template <class T> T maxim (T a, T b) { if(a>b) return a; else return b; }
Functii Template (Sabloane) Tipul returnat de
functie este T, la fel ca si tipurile parametrilor
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
10
int main() { int a=2, b=10; cout<<maxim<int>(a,b)<<endl; double x=7.9, y=1.234; cout<<maxim<double>(x,y)<<endl; }
Functii Template (Sabloane)
Tip efectiv folosit de functie in loc de T
Tip efectiv folosit de functie in loc de T
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
11
După execuția programului se afișează următoarele rezultate:
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
12
Exemplu 2:
Program ce ilustrează o funcție template, unde T poate fi int, double și altele.
Singura diferență dintre aceste funcții este ca diferă tipul parametrilor formali.
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
13
#include<iostream.h> template <class T> void
interschimba(T& a, T& b) { T aux; aux = a; a = b; b = aux; }
Functii Template (Sabloane)
Tipul returnat de functie este void, iar tipul parametrilor
este T
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
14
int main() { int a=10,b=3; cout<<"valorile initiale \n"; cout<<a<<" "<<b<<endl; interschimba<int>(a,b); cout<<"valorile finale \n"; cout<<a<<" "<<b<<endl; }
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
15
După execuția programului se afișează următoarele rezultate:
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
16
Definirea de parametri tip se face folosind cuvântul rezervat template urmat de <class T>, adică:
Functii Template (Sabloane)
template <class T> template <class T>
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
17
Această construcție se mai numește prefix template și spune compilatorului că definiția sau prototipul care urmează este un template și că T este un parametru tip. ( În acest context, class înseamnă de fapt tip ).
Definiția unei funcții template este, de fapt, o mulțime de definiții de funcții.
Pentru exemplul nostru, parametrul de tip T se înlocuiește cu un nume de tip.
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
18
Când folosim funcții template, putem spune că exprimăm un algoritm general în C++.
Acesta este un exemplu simplu de algoritm abstract.
Algoritmii abstracți ignoră detaliile, continând partea semnificativă a algoritmului.
Dacă funcția are mai mulți parametri tip atunci declarația template-ului se generalizează imediat.
Pentru doi parametri, scriem:
Functii Template (Sabloane)
template <class T1, class T2> template <class T1, class T2>
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
19
Exemplu 3:
Fie programul C++: // Ilustrarea unor situații neobișnuite
#include <iostream.h> template <class T1, class T2> void
f(T1 a, T2 b) { cout << a <<"\t"<< b; }
Functii Template (Sabloane)
Tipul returnat de functie este void, iar
tipurile parametrilor sunt diferite: T1 si T2
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
20
int main() { f(40000, 6); cout<<"\n"; f(1, 2.3); cout<<"\n"; f(1, 'a'); cout<<"\n"; f(2.3, 1); cout<<"\n"; }
Functii Template (Sabloane)
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
21
După execuția programului se afișează următoarele rezultate:
Functii Template (Sabloane)
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
23
a) Sintaxa pentru clasele template este aceeași ca template-urile funcțiilor:
template <class T> class nume_clasa { …… }
template <class T> class nume_clasa { …… }
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
24
b) Antetul unei metode se declară în interiorul clasei la fel ca la clasele obișnuite, iar definiția metodei care se construiește în afara clasei se face adăugând clasa din care face parte.
2. Clase template
template <class T> tip_metoda nume_clasa<T> :: nume_metoda (lista_parametri_formali) { ….. }
template <class T> tip_metoda nume_clasa<T> :: nume_metoda (lista_parametri_formali) { ….. }
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
25
c) Pentru a defini un obiect al unei clase template procedăm în același fel ca și la definirea obiectelor de până acum.
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
26
Exemplu 4:
Să se construiască o clasă numită
vector care să gestioneze un vector de n
elemente de tip T, vector alocat dinamic.
Clasa se va utiliza în funcția principală
pentru T=int și pentru T=double.
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
27
template <class T> class vector{ int n; T* adr; public: vector(int n); ~vector(); T& operator[] (int k); // supraîncărcarea
operatorului [], pt. returnarea pozitiei elementului curent din vector
}
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
28
template <class T> vector <T>::vector(int n)
{ this->n = n; adr = new T[n]; }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
29
template <class T> vector <T>::~vector() { delete[ ] adr; } template <class T> T& vector
<T>::operator[ ] (int k) { return adr[k]; }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
30
int main() { vector<int> v(10); v[1] = 3; cout<<v[1]<<endl; vector<double> w(5); w[0] = 77; cout<<w[0]<<endl; }
2. Clase template
Tip efectiv folosit de clasa in loc de T
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
31
După execuția programului se afișează următoarele rezultate:
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
32
Exemplu 5:
Se cere să se scrie o clasă numită stiva care
gestionează o stivă memorată ca lista liniară
simplu înlănțuită.
Fiecare nod al listei reține: o valoare de tipul formal T,
și în plus, adresa următorului element din stivă (cf. principiului
stivei este vorba de elementul precedent din listă!).
Clasa se va testa pentru T=int și pentru
T=float.
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
33
Structura unui nod al stivei va fi definită cu ajutorul unei struct, deoarece trebuie să rețină pe lângă informația propriu-zisă de tipul T și adresa elementului următor din stivă.
struct nod { T info; // T este tipul formal template
nod *adr; // adr este un pointer catre urmator
element al stivei
}
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
34
Clasa stiva va contine: 1. Date membru: varf – reprezentand adresa ultimului element al
stivei 2. Metode membru: stiva() – constructor de initializare al stivei void push(T v) – functie(metoda) care adauga un
element in stiva, element de tipul formal T T pop() – functie care elimina un element din
stiva int vida() – functie care testeaza daca stiva este
vida sau nu
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
35
#include<iostream.h> template <class T> class stiva{ struct nod { T info; nod* adr; }; nod* varf; public: stiva(); void push(T v); T pop(); int vida(); };
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
36
template <class T> stiva <T>::stiva() { varf=0; }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
37
template <class T> void stiva <T>::push(T v) { nod* c=new nod; c->info=v; c->adr=varf; varf=c; }
2. Clase template
Vârful stivei(varf)
Baza stivei
c
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
38
template <class T> T stiva <T>::pop() { nod* c=varf; T nr; varf=varf->adr; nr=c->info; delete c; return nr; }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
39
template <class T> int stiva <T>::vida() { if(varf==0) return 1; else return 0; }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
40
int main() { cout<<"Stiva de elemente nr. intregi\n" ; stiva<int> st; st.push(1); st.push(2); st.push(3); while(!st.vida()) cout<<st.pop()<<"\n";
2. Clase template
Tip efectiv folosit de clasa in loc de T
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
41
cout<<"Stiva de elemente nr. reale\n" ; stiva<float> st1; st1.push(3.45); st1.push(8.907); st1.push(1.23); while(!st1.vida()) cout<<st1.pop()<<"\n"; }
2. Clase template
Tip efectiv folosit de clasa in loc de T
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
42
După execuția programului se afișează următoarele rezultate:
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
43
Exemplu 6:
În continuare, prezentăm un program C++ care descrie o clasă template a cărei obiecte sunt liste.
Listele sunt structuri înlănțuite de orice tip (int, double, char, ...)
Fiecare nod al listei reține o valoare de tipul formal T, și în plus, adresa următorului element din listă.
Clasa se va testa pentru T=int și pentru T=float.
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
44
Structura unui nod al listei va fi definită cu ajutorul unei struct, deoarece trebuie să rețină pe lângă informația propriu-zisă de tipul T și adresa elementului următor din listă:
struct nod { T info; // T este tipul formal template
nod *adr; // adr este un pointer catre
urmator element al listei
}
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
45
Clasa lista va conține: 1. Date membru: prim – reprezentand adresa primului element al listei
2. Metode membru: lista() – constructor de initializare al listei lista(int n) – constructor care incarca n elemente in
lista void adaugare_element(T p) – functie(metoda) care
adauga un element in lista, element de tipul formal T void stergere_element(T p) – functie(metoda) care
sterge un element in lista, element de tipul formal T void afiseaza_lista() – functie care afiseaza
elementele din lista
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
46
#include<iostream.h> template <class T> class lista{ struct nod { T info; nod* adr; };
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
47
nod *prim; public: lista(); lista(int n); void adaugare_element(T p); // va fi
definita ulterior
void stergere_element(T p); // va fi
definita ulterior
void afiseaza_lista(); };
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
48
template <class T> lista<T>::lista() { prim = NULL; }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
49
template <class T> lista<T>::lista(int n) { int i; T inf; nod *p,*ultim; cout<<"Construim lista care are "<<n<<"
elemente\n"; cout<<"Dati informatia pt. primul element "; cin>>inf; prim->info=inf; prim->adr=NULL; ultim=prim;
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
50
for(i=2;i<=n;i++) { cout<<"Dati inf = "; cin>>inf; p=new nod; p->info=inf; p->adr=NULL; ultim->adr=p; ultim=p; } }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
51
template <class T> void lista<T> :: afiseaza_lista()
{ nod *p; p=prim; while(p!=NULL) { cout<<p->info<<" "; p=p->adr; } }
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
52
int main()
{
cout<<"Lista de elemente nr. intregi\n";
lista <int>l(4);
l.afiseaza_lista();
cout<<endl<<"Lista de elemente nr. reale\n";
lista <float>l1(6);
l1.afiseaza_lista();
}
2. Clase template
Tip efectiv folosit de clasa in loc de T
Tip efectiv folosit de clasa in loc de T
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
53
După execuția programului se afișează următoarele rezultate:
2. Clase template
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
54
Problema rezolvata
Sa se scrie un program prin care sa se exemplifice utilizarea unei functii sablon(template) de ordonare crescatoare a oricarui tip de vector (de numere intregi, numere reale, etc.). Se va folosi metoda bubblesort.
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
55
#include <iostream.h>
template <class T> void bubble_sort( T *vector, int numar)
// T *vector - pointer la un vector de tipul sablon
// int numar - numarul de elemente din vector
{
int i, j;
T t;
for(i=0; i<numar; i++)
for(j=i+1; j<numar; j++)
if(vector[i] > vector[j]) {
t = vector[i];
vector[i] = vector[j];
vector[j] = t;
}
}
Metoda bubble sort: se compara fiecare element cu toate celelalte aflate in
dreapta sa in vector
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
56
int main()
{
int vector_int[7] = {7, 5, 4, 3, 9, 8, 6};
double vector_double[5] = {4.3, 2.5, -0.9, 100.2, 3.0};
int i;
cout << "\nVectorul nesortat de numere intregi: ";
for(i=0; i<7; i++)
cout<<vector_int[i]<<" ";
cout << "\nVectorul nesortat de numere reale: ";
for(i=0; i<5; i++)
cout<<vector_double[i]<<" ";
13.11.2013 Curs - Programare orientată pe obiecte C++/Java
57
bubble_sort(vector_int, 7);
cout << "\nVectorul SORTAT de numere intregi: ";
for(i=0; i<7; i++)
cout<<vector_int[i]<<" ";
bubble_sort(vector_double, 5);
cout << "\nVectorul SORTAT de numere reale: ";
for(i=0; i<5; i++)
cout<<vector_double[i]<<" ";
}