130 likes | 270 Views
Tipi parametrici. Collezioni generiche. Strutture matematiche parametriche. Funzioni parametriche sul tipo: modelli. Vi sono algoritmi che non dipendono dal tipo dei dati che elaborano: void swap ( int & m, int & n) { int temp = m; m = n; n = temp; } void swap ( string & s, string & t)
E N D
Tipi parametrici Collezioni generiche. Strutture matematiche parametriche Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Funzioni parametriche sul tipo: modelli Vi sono algoritmi che non dipendono dal tipo dei dati che elaborano: void swap (int& m, int& n) { int temp = m; m = n; n = temp; } void swap (string& s, string& t) { string temp = s; s = t; n = temp; } In C++ possiamo parametrizzare sul tipo degli argomenti: template <class T> void swap (T& m, T& n) { T temp = m; m = n; n = temp; } modello Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Chiamata di modelli di funzioni Quando occorre chiamare una funzione parametrizzata sul tipo, il C++ consente di lasciare quest’ultimo implicito, deducendolo dal contesto di chiamata: int m = 6; n = 34; swap(n, m); string(s1 = “Mario Rossi”, s2 = “Giovanni Bianchi”); swap(s1, s2); Nota: la dichiarazione <class T> significa “per ogni tipo T” (non necessariamente una classe (es. T = int); inoltre è possibile parametrizzare su più di un tipo: template <class X, class Y, class Z> Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Overloading di operatori Come per le funzioni, anche gli operatori possono essere sovraccaricati in C++: class Complex { public: Comlex(float re=0, float im=0) {real = re; imag = im;} Complex operator+(const Complex&); private: float real, imag; }; Complex Complex::operator+(const Complez& z) { return Complex(real + z.real; imag + z.imag);} // ... Complex A = C + B; // equivale a C.operator+(B) Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Strutture dati parametriche La maggior parte delle strutture dati non elementari è parametrica nel tipo dei dati contenuti: vettori, liste, pile, code, alberi, ecc. Sintassi C++: template <class T, ...> class X { ... } Come accade per i modelli di funzioni, quelli delle classi generano classi per istanziazione del parametro con un tipo: X<short> x; // x ha classe ottenuta da X // quando T = short X<string> y; // y ha classe ottenuta da X // quando T = string Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Metodi delle strutture parametriche I metodi di una classe parametrica sono in effetti dei modelli: template <class T> class X { T square (T x) {return x*x; } }; viene trattato come template <class T> T square (T x) {return x*x; } Dunque il modello X genera la classe X<short> equivalente a: class Xshort { short square (short x) {return x*x; } }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Classe Stack parametrica template <class T> class Stack { public: Stack (int s = 100) { size = s; top = -1; data = new T[size]; } ~Stack {delete [] data;} void push (T x) {data[++top] = x;} T pop () {return data[top--];} bool isEmpty () {return top == -1;} bool isFull () {return top == size-1;} private: int size, top; T* data; }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Elementi della lista: subtyping class ListEl; typedef ListEl *PListEl; class ListEl { friend class List; friend class ListIterator; private: Object info; PListEl next; ListEl (Object obj, PListEl nxt) { info = obj; next = nxt;} }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Liste parametriche template <class T> class ListEl { friend class List<T>; friend class LisIterator<T>; private: T info; ListEl <T>* next; ListEl (T x, ListEl<T>* n) { info = x; next = n;} }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Liste: subtyping class ListEl; typedef ListEl *PListEl; class List : public Collection {friendclass ListIterator; public: void insert (PObject obj); // inserimento in testa void insert (int index, PObject obj); // overloading: inserimento con indice bool empty (void) { return first == NULL;} PIterator iterator (void); // ... protected: PListEl first; }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Liste parametriche template <class T> class List {friend class LisIterator<T>; public: void insert (Tx); // inserimento in testa void insert (int index, Tx); // overloading: inserimento con indice bool empty (void) { return first == NULL;} ListIterator<T>* iterator (void); // ... protected: ListEl<T>* first; }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Iteratori sulle liste: subtyping class ListIterator; typedef ListIterator *PListIterator; class ListIterator : public Iterator { public: bool hasNext (void); Object next (void); void reinit() {current = mylist->first;} ListIterator (PList l) { mylist = l; current = l->first;} private: PList mylist; PListEl current; }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9
Iteratori su liste parametriche template <class T> class ListIterator { public: bool hasNext (void); T next (void); void reinit() {current = mylist->first;} ListIterator (const List<T>l) { mylist = l; current = l->first;} private: constList<T>* mylist; ListEl<T>* current; }; Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9