9.1. No?iune de clas? generic?
9.1. No?iune de clas? generic?
Clase asemeni func?iilor generice pot ?i ele s? depind? de tipuri parametrizate.
Clasa a c?rei declarare este prefixat? cu indicarea unui sau mai multor tipuri parametrizate, care vor fi concretizate ?n locurile instan?ierei acestei clase, se nume?te clas? generic? (sau clas? ?ablon, sau clas? de tip template) |
Forma general? de declarare a unei clase generice este urm?toarea:
template <class tip_1[,class tip_2 ...]> class nume_clas? [:[mod_mo?tenire] nume_clas?_de_baz?]{ // Corpul clasei … }; |
Drept exemplu transform?m ?n generic? clasa vectorp din capitolul despre func?ii virtuale. De data aceasta pointerii vectorului vor indica spre elementele de tip parametrizat.
#include "iostream.h" #include "iostream.h" // // C L A S S V E C T O R P // template <class T> class vectorp { protected: T **vp; // vector de pointeri cu tipul de baz? T int n; // num?rul de pointeri ?n vector public: vectorp(int n_init) { n = n_init; vp = new T* [n]; // aloc?m memoria pentru vector de // n pointeri } ~vectorp() { for(int i=0; i<n; i++) // mai ?nt?i elimin?m // obiectele indicate delete vp[i]; // de c?tre pointeri din // vectorul de pointeri delete []vp; // apoi elimin?m ?nsu?i // vectorul de pointeri } T* &operator[](int i) { return *(vp+i); // returneaz? referin?a la un pointer din // vector } void sort(); friend ostream& operator << (ostream &stream, const vectorp<T>& vect); }; template <class T> void vectorp<T>::sort() { for(int i=1; i<n; i++) for(int j=i; (j>0)&&(**(vp+j)<**(vp+j-1)); j--) { // aici schimb?m cu locurile valorile a doi pointeri din // vector T *pt = *(vp+j); *(vp+j) = *(vp+j-1); *(vp+j-1) = pt; } } template <class T> ostream& operator << (ostream &stream, const vectorp<T>& vect) { // vom afi?a obiectele indicate de c?tre pointeri din vector for(int i=0; i<vect.n; i++) stream << *vect[i] << endl; return stream; } |
Re?ine?i cum se descriu func?iile membre ale unei clase generice ?n afara clasei.
?n func?ia main() instan?iem clasa vectorp cu tipuri concrete.
void main() void main() { // Exemplu cu un vector de pointeri spre numere reale vectorp<double> vd(6); // declar?m obiectul vd utiliz?nd // clasa generic? vectorp vd[0] = new double(7.1); // operatorul de indexare [] este // supra?nc?rcat ?n clasa vectorp vd[1] = new double(2.0); vd[2] = new double(-3.14); vd[3] = new double(0.0); vd[4] = new double(2.5); vd[5] = new double(1.0); cout << "Vector de reale initial:" << endl; cout << vd; vd.sort(); cout << "Vector de reale dupa sortare:" << endl; cout << vd << endl; // Exemplu cu un vector de pointeri spre numere intregi vectorp<int> vi(9); vi[0] = new int(7); vi[1] = new int(4); vi[2] = new int(1); vi[3] = new int(-5); vi[4] = new int(9); vi[5] = new int(3); vi[6] = new int(4); vi[7] = new int(2); vi[8] = new int(5); cout << "Vector de intregi initial:" << endl; cout << vi; vi.sort(); cout << "Vector de intregi dupa sortare:"<< endl; cout << vi << endl; } //Acest program afi?eaz? urm?torul text: Vector de reale initial: 7.1 2 -3.14 0 2.5 1 Vector de reale dupa sortare: -3.14 0 1 2 2.5 7.1 Vector de intregi initial: 7 4 1 -5 9 3 4 2 5 Vector de intregi dupa sortare: -5 1 2 3 4 4 5 7 9 |
Pentru a explica cum va lucra clasa generic? vectorp cu obiecte, declar?m clasa string care ne va u?ura efectuarea opera?iilor cu ?iruri de caractere. Inser?m ?nainte de func?ia main(), ?n programul precedent, urm?torul cod:
// // // C L A S S S T R I N G // class string { protected: char*s; public: string(char* s_init="") { s = new char[strlen(s_init)+1]; strcpy(s, s_init); } virtual ostream& print(ostream &stream=cout) { return stream << s; } friend ostream& operator << (ostream &stream, const string& str) { return str.print(stream); } int operator < (string& str2) { return strcmp(this->s, str2.s)<0; } }; La ?nceputul programului ad?ugam #include "string.h" iar la func?ia main() ad?ug?m urm?torul cod: // Exemplu cu un vector de pointeri spre ?iruri vectorp<string> vs(10); vs[0] = new string("Red"); vs[1] = new string("White"); vs[2] = new string("Blue"); vs[3] = new string("Yellow"); vs[4] = new string("Magenta"); vs[5] = new string("Cyan"); vs[6] = new string("Black"); vs[7] = new string("Green"); vs[8] = new string("Orange"); vs[9] = new string("Violet"); cout << "Vector de siruri initial:" << endl; cout << vs; vs.sort(); cout << "Vector de siruri dupa sortare:" << endl; cout << vs << endl; //Acum programul nostru va mai afi?a: Vector de siruri initial: Red White Blue Yellow Magenta Cyan Black Green Orange Violet Vector de siruri dupa sortare: Black Blue Cyan Green Magenta Orange Red Violet White Yellow |
_________________________
Autorul: dr.conf. S. Pereteatcu
Оставить комментарий