Professional Documents
Culture Documents
Clase parametrizate
Declaraie template Definirea membrilor Instaniere (Specializare), Specializare utilizator Friend n template Membri statici n template
POO(C++)
Gh GRIGORAS
Clase parametrizate
Programare generic : programare ce utilizeaz tipurile ca parametri n C++ - mecanismul template: clase template, funcii template Programatorul scrie o singur definiie template iar C++, pe baza parametrilor, genereaz specializri care sunt compilate cu restul programului surs O funcie template poate fi suprancrcat cu:
Funcii template cu acelai nume dar parametri template diferii Funcii non template cu acelai nume dar cu ali parametri
Template-uri
//Supraincarcare functii void swap(int& x, int& y){ int aux = x; x = y; y = aux; } void swap(char& x, char& y){ char aux = x; x = y; y = aux; } void swap(float& x, float& y){ float aux = x; x = y; y = aux; }
POO(C++) Gh GRIGORAS 3
Template-uri
int x = 23, y = 14; char c1 = 'o', c2 = '9'; double u = .5, v = 5.5; swap(x, y); swap(u, v); swap(c1, c2);
Polimorfism parametric:
utilizarea aceluiai nume pentru mai multe nelesuri(polimorfism). nelesul este dedus din tipul parametrilor (parametric).
Gh GRIGORAS 4
POO(C++)
Template-uri
POO(C++)
Gh GRIGORAS
Template-uri
template <class T> void naiveSort(T a[], int n) { for (int i=0; i<n-1; i++) for(int j=i+1; j<n; j++) if (a[i] > a[j]) swap<T>(a[i], a[j]); };
POO(C++)
Gh GRIGORAS
Template-uri
La apel, pentru n trebuie transmis o constant:
int i; double x[5] = {2,1,3,5,4}; naivSort<double>(x, 5); for (i=0; i<5; i++) cout << x[i] << ", "; cout << endl; double y[5] = {2,1,3,5,4}; naivSort2<double, 5>(y); for (i=0; i<5; i++) cout << x[i] << ", "; cout << endl; int n = 5; double z[5] = {2,1,3,5,4}; naivSort2<double, n>(z);
// eroare
POO(C++)
Gh GRIGORAS
D. Lucanu
POO Principii
Clase parametrizate
parametru parametru
D. Lucanu
POO Principii
parametriza te
parametri
10
D. Lucanu
POO Principii
Clase parametrizate
template< class T, int i > class MyStack{}; template< class T1, class T2 > class X{}; template< typename T1, typename T2 > class X{}; template<class T> class allocator {}; template<class T1, typename T2 = allocator<T1> > class stack { }; stack<int> MyStack; // al doilea argument este implicit class Y {...}; template<class T, T* pT> class X1 {...}; template<class T1, class T2 = T1> class X2 {...}; Y aY; X1<Y, &aY> x1; X2<int> x2;
POO(C++)
Gh GRIGORAS
12
Clase parametrizate
Funciile membru ale unei clase template sunt funcii template parametrizate cu parametrii clasei template respective Definirea membrilor unei clase template:
Definiie inline, la specificarea clasei nu este specificat explicit template Definiie n afara specificrii clasei trebuie declarat explicit template:
template <lista_argumente_template > nume_clasa_template<argum>::nume_functie_membru(parametri) { //Corp functie }
Clase parametrizate
Instaniere template: procesul de generare a unei declaraii de clas (funcie) de la o clas(funcie) template cu argumente corespunztoare
template class MyStack<class T,int n>{}; template class MyStack<int, 6>; template MyStack<int, 6>::MyStack(); template<class T> void f(T) {...} template void f<int> (int); template void f(char);
POO(C++) Gh GRIGORAS 14
POO(C++)
Gh GRIGORAS
15
Exemplul 1 - cont
template <class Elt> Cell<Elt>::Cell(const Cell<Elt>& c) { val = new Elt; *val = *(c.val); } template <class Elt> Cell<Elt>::~Cell() { delete val; } template <class Elt> Cell<Elt>& Cell<Elt>::operator =(const Cell<Elt>& c) { //.. *val = *(c.val); return *this; }
POO(C++) Gh GRIGORAS 16
Exemplul 1 - cont
#include "cell.h" template <class Elt> class Array { public: Array(int = 1); Array(const Aray&); ~Array(); Elt get(int); void set(int, Elt); Array& operator=(const Array&); Cell<Elt>& operator[](int) const Cell<Elt>& operator[](int) const; private: Cell<Elt> *arr; int nOfComp; };
POO(C++)
Gh GRIGORAS
17
Exemplul 1 - cont
template <class Elt> Array<Elt>::Array(int nMax) { arr = new Cell<Elt>[nMax]; if(arr == NULL) throw Memorie insuficienta "; nOfComp = nMax; }; template <class Elt> Array<Elt>::~Array() { delete[] arr; }; template <class Elt> Elt Array<Elt>::get(int i) { if((i<0)||(i>=nOfComp)) throw "Index gresit."; return arr[i].getVal(); };
POO(C++) Gh GRIGORAS 18
Exemplul 1 - cont
Template: Suprancrcare operatori
template <class Elt> Cell<Elt>& Array<Elt>::operator[](int i) { if((i<0)||(i>=nOfComp)) throw "Index gresit."; return arr[i]; }
// pentru a sorta tablouri de celule de int-uri // trebuie definit operatorul de comparare: bool operator >(const Cell<int>& x, const Cell<int>& y) { return x.getVal() > y.getVal(); }
POO(C++)
Gh GRIGORAS
19
Exemplul 1 - cont
// sortare prin insertie template <class T> void insert_sort(Array<T>& a, int n) { int i,j; Cell<T> temp; for(i=1;i<n;i++) { temp = a[i]; j = i - 1 ; while((j >= 0) && (a[j] > temp)) { a.set(j+1, a[j].getVal()); j--; } if (i != (j-1)) a.set(j+1, temp.getVal()); } } typedef Cell<int> Int; typedef Cell<char> Char;
POO(C++) Gh GRIGORAS 20
Exemplul 2
template <class T> T& Vector<T>::operator [](int i) { cout << "Vector<T>::operator [](int i)" << endl; return tab[i]; } template <class T> const Vector<T>& Matrice<T>::operator [](int i) const { cout << "Matrice<T>::operator [](int i) const" << endl; if (i < 0 || i >= m) throw "index out of range"; return tabv[i]; } Vector<int> v(5); v[3] = 3; // apel varianta nonconst const Vector<int> vv(5); vv[4] = 4;// apel varianta const Matrice<double> m(3,5); m[1][2] = 5.0; const Matrice<double> mm(3,5); mm[2][3] = 7.0;
POO(C++)
Gh GRIGORAS
22
Specializri
O versiune a unui template pentru un argument template particular este numit o specializare O definiie alternativ pentru o clas(funcie) template ( de ex. pentru a funciona cnd argumentul template este pointer) este numit specializare definit de utilizator
POO(C++)
Gh GRIGORAS
23
Specializri:
POO(C++)
Gh GRIGORAS
24
Clase parametrizate
Dou instanieri ale unei clase template sunt echivalente dac parametrii template ce reprezint tipuri sunt aceeai iar ceilali au aceleai valori
MyString<char> s1; MyString<unsigned char> s2; typedef unsigned char Uchar; MyString <Uchar> s3;
POO(C++)
Gh GRIGORAS
27
POO(C++)
Gh GRIGORAS
29
Derivare - parametrizare
Se poate defini o clas parametrizat prin derivare
de la o clas parametrizat de la o instan a unei clase parametrizate de la o clas obinuit
Se poate defini o clas obinuit prin derivare de la o instan a unei clase parametrizate
POO(C++) 2005-2006 Gh GRIGORAS 31
Derivare - parametrizare
template <class T> class Fisier: protected fstream {}; template <class T> class FisierCitire: public virtual Fisier<T> {};
template <class Type> class safe_stack : public stack<Type> { public: // push, pop sigure void push(Type c) { assert (!full()); stack<Type>::push(c); } char pop() {assert (!empty()); return (stack<Type>::pop());} };
POO(C++) 2005-2006 Gh GRIGORAS 34
ios<>
istream<>
ostream<>
ostringstream<> ofstream<>
fstream<>
stringstream<>
POO(C++) 2005-2006
Gh GRIGORAS
35
streambuf<>
filebuf<>
stringbuf<>
POO(C++) 2005-2006
Gh GRIGORAS
37
Clasa basic_iostream
template <class E, class T = char_traits<E>> class basic_iostream : public basic_istream<E, T>, public basic_ostream<E, T> { public: explicit basic_iostream(basic_streambuf<E, T>* sb); virtual ~basic_iostream(); };
POO(C++) 2005-2006
Gh GRIGORAS
38
POO(C++) 2005-2006
Gh GRIGORAS
39
Clasa ostream
Un obiect din ostream (flux de ieire) este un mecanism pentru conversia valorilor de diverse tipuri n secvene de caractere n <iostream>:
ostream cout; //fluxul standard de iesire ostream cerr; // mesaje eroare,fara buffer ostream clog; // mesaje eroare,cu buffer
POO(C++) 2005-2006
Gh GRIGORAS
40
operator<< (n ostream)
basic_ostream& operator<< (const char *s); basic_ostream& operator<< (char c); basic_ostream& operator<< (bool n); basic_ostream& operator<< (short n); basic_ostream& operator<< (unsigned short n); basic_ostream& operator<< (int n); basic_ostream& operator<< (unsigned int n); basic_ostream& operator<< (long n); basic_ostream& operator<< (unsigned long n); basic_ostream& operator<< (float n); basic_ostream& operator<< (double n); basic_ostream& operator<< (long double n); basic_ostream& operator<< (void * n); basic_ostream& put(E c); // scrie c basic_ostream& write(E *p, streamsize n); // scrie p[0],,p[n-1] basic_ostream& flush(); // goleste bufferul pos_type tellp(); // pozitia curenta basic_ostream& seekp(pos_type pos); // noua positie pos basic_ostream& seekp(off_type off, ios_base::seek_dir way); // pozitia way (= beg, cur, end) + off
POO(C++) 2005-2006
Gh GRIGORAS
41
POO(C++) 2005-2006
Gh GRIGORAS
42
Manipulatori
MANIPULATOR
endl ends flush dec hex oct ws skipws noskipws showpoint noshowpoint showpos noshowpos boolalpha noboolalpha POO(C++) 2005-2006 Scrie newline Scrie NULL in string Goleste Baza 10 Baza 16 Baza 8 Ignor spaiile la intrare Ignor spaiile Nu ignor spaiile Se scrie punctul zecimal i zerourile Nu se scriu zerourile, nici punctul Scrie + la numerele nenegative Nu scrie + la numerele nenegative Scrie true si false pentru bool Scrie 1 si 0 pentru bool Gh GRIGORAS
EFECTUL
FISIERUL
iostream iostream iostream iostream iostream iostream iostream iostream iostream iostream iostream iostream iostream iostream iostream 43
Manipulatori
MANIPULATOR
scientific fixed left right internal setw(int) setfill(char c) setbase(int) setprecision(int) setiosflags(long) resetiosflags(long)
EFECTUL
Notaia tiinific pentru numere reale Notaia punct fix pentru numere reale Aliniere stnga Aliniere dreapta Caract. de umplere intre semn si valoare Seteaza dimensiunea cmpului Caracterul c nlocuete blancurile Setarea bazei Seteaza precizia in flotant Seteaza bitii pentru format Reseteaza bitii pentru format
FISIERUL
iostream iostream iostream iostream iostream iomanip iomanip iomanip iomanip iomanip iomanip
POO(C++) 2005-2006
Gh GRIGORAS
44
double a = 12.05, b = 11.25, c = -200.89; cout << a << ',' << b << ',' << c << endl; cout << setfill('*') << setprecision(3); cout << setw(10) << a << endl; cout << setw(10) << b << endl; cout << setw(10) << c << endl; cout << setw(10) << showpoint << c << endl; cout << setfill(' ') << right << showpoint; cout << setw(15) << setprecision(5) << c << endl; cout << scientific << c << endl; char d; cin >> noskipws; while(cin >>d) cout << d;
12.05,11.25,-200.89 ******12.1 ******11.3 ******-201 *****-201. -200.89 -2.00890e+002 text pentru test text pentru test
POO(C++) 2005-2006 Gh GRIGORAS 45
Clasa istream
Un obiect din istream (flux de intrare) este un mecanism pentru conversia caracterelor n valori de diverse tipuri n <iostream>: istream cin; //fluxul standard de intrare n basic_istream este definit operator>> pentru tipurile fundamentale
POO(C++) 2005-2006
Gh GRIGORAS
46
POO(C++) 2005-2006
Gh GRIGORAS
47
Fiiere
ntr-un program C++ fluxurile standard cin, cout, cerr, clog sunt disponibile; corespondena lor cu dispozitivele (fiierele ) standard este fcut de sistem Programatorul poate crea fluxuri proprii obiecte ale clasei fstream (ifstream, ofstream). Ataarea fluxului creat unui fiier sau unui string se face de programator:
la declarare cu un constructor cu parametri dup declarare prin mesajul open()
POO(C++) 2005-2006 Gh GRIGORAS 48
Fiiere
Constructorii clasei fstream:
explicit basic_fstream(); explicit basic_fstream(const char *s, ios_base::openmode mode = ios_base::in | ios_base::out);
Metode:
bool is_open() const; void open(const char *s, ios_base::openmode mode = ios_base::in | ios_base::out); void close();
POO(C++) 2005-2006 Gh GRIGORAS 49
Fiiere de intrare
Constructorii clasei ifstream:
explicit basic_ifstream(); explicit basic_ifstream(const char *s, ios_base::openmode mode = ios_base::in);
Metode:
bool is_open() const; void open(const char *s, ios_base::openmode mode = ios_base::in); void close();
POO(C++) 2005-2006 Gh GRIGORAS 50
#include <fstream> #include <iostream> #include <string> using namespace std; int main () { string line; ifstream myfile ("file.cpp"); if (myfile.is_open()) { while (! myfile.eof() ) { getline (myfile,line); cout << line << endl; } myfile.close(); }else cout << "Unable to open file"; return 0; }
POO(C++) 2005-2006 Gh GRIGORAS 51
Fiiere de ieire
Constructorii clasei ofstream:
explicit basic_ofstream(); explicit basic_ofstream(const char *s, ios_base::openmode which = ios_base::out | ios_base::trunc);
Metode:
bool is_open() const; void open(const char *s, ios_base::openmode mode = ios_base::out | ios_base::trunc); void close();
POO(C++) 2005-2006 Gh GRIGORAS 52
#include <iostream> #include <fstream> using namespace std; int main () { ofstream myfile ("example.txt"); if (myfile.is_open()){ myfile << "This is a line.\n"; myfile << "This is another line.\n"; myfile.close(); } else cout << "Unable to open file"; return 0; }
POO(C++) 2005-2006 Gh GRIGORAS 53
ios_base::openmode
app, poziionare la sfrit nainte de fiecare inserie ate, poziionare la sfrit la deschiderea fiierului binary, citirea fiierului n mod binar i nu n mod text in, permite extragerea (fiier de intrare) out, permite inseria (fiier de ieire) trunc, trunchiaz un fiier existent la prima creare a fluxului ce-l controleaz
POO(C++) 2005-2006 Gh GRIGORAS 54
Clasa stringstream
Permite ca stringurile s fie tratate ca fiiere:
explicit basic_stringstream(ios_base::openmode mode = ios_base::in | ios_base::out);
explicit basic_stringstream(const basic_string<E,T,A>& x, ios_base::openmode mode = ios_base::in | ios_base::out);
POO(C++) 2005-2006
Gh GRIGORAS
55
#include <iostream> #include <sstream> using namespace std; int main() { stringstream s("This is initial string."); // get string string str = s.str(); cout << str << endl; // output to string stream s << "Numbers: " << 10 << " " << 123.2; int i; double d; s >> str >> i >> d; cout << str << " " << i << " " << d; return 0; }
POO(C++) 2005-2006
Gh GRIGORAS
56