Está en la página 1de 158

Programarea calculatoarelor II (C++)

Dorel Lucanu

Dorel Lucanu

Programarea calculatoarelor (C++)

Bibliografie

! Liviu Negrescu : Limbajele C si C++ pentru incepatori, vol II, III, Microinformatica, ClujNapoca ! H. Schildt: C++ manual complet, Teora, 2000 ! D. Kaler, M.J. Tobler, J. Valter: C++, Teora, 2000 ! Bjarne Stroustrup: The C++ Programming Language, Adisson-Wesley, 3nd edition, 1997 ! Stanley B. Lippman: C++ Primer, Addison Wesley, 1992 Manuale electronice ! Peter Mller : Introduction to Object-Oriented Programming Using C++ ! Bruce Eckel : Thinking in C++, 2nd Edition ! *** : Online C++ tutorial

Dorel Lucanu

Programarea calculatoarelor (C++)

Curs 1 ! Incapsulare si ascundere "Clase si obiecte, clase atribute, metode, stari declararea claselor si obiectelor in C++ utilizarea obiectelor in C++ constructori, destructori exemplul Contor: .h, .cpp, demo "Tipuri abstracte de data si obiecte Exemplul Stiva: .h, .cpp, demo "Utilizare de clase: string.h, string.cpp

Dorel Lucanu

Programarea calculatoarelor (C++)

Obiecte si clase
! O prima definitie pentru obiecte si clase: " Un obiect este caracterizat de: nume atribute o multime de stari metode (servicii) " O clasa descrie unul sau mai multe obiecte ce pot fi precizate printr-un set uniform de atribute si metode. ! Reprezentarea grafica

nume atribute metode

Dorel Lucanu

Programarea calculatoarelor (C++)

Clasa Contor Un contor are o valoare curenta si o valoare de resetare, si poate fi incrementat, decrementat, resetat, si pot fi citite valorile curenta si de resetare

Contor
val : int reset_val : int

get_val() get_reset_val() increment() decrement() reset()

Dorel Lucanu

Programarea calculatoarelor (C++)

Incapsulare si ascundere
! Incapsulare: datele si operatiile asupra lor sint incluse in aceeasi unitate sintactica (clasa)

Contor val increment( ) val increment( )

!Ascunderea informatiei modul de structurare a datelor nu este cunoscut actiunile asupra datelor sint realizate numai prin operatiile (metodele) clasei si anumite actiuni pot fi ascunse

C.val++ C.increment() OK!

Dorel Lucanu

Programarea calculatoarelor (C++)

Contor.h
class Contor { public: // Constructori/destructori Contor(); ~Contor(); // metode int get_val(); int get_reset_val(); void increment(); void decrement(); void reset() { val = val_reset; } private: // atribute int val; int val_reset; };

Dorel Lucanu

Programarea calculatoarelor (C++)

Contor.cpp
#include "contor.h" Contor::Contor() { val = 0; val_reset = 0; } void Contor::increment() { val++; } void Contor::decrement() { val--; }

Contor_demo.cpp
Contor intcount; intcount.increment(); cout << intcount.get_val;
Dorel Lucanu Programarea calculatoarelor (C++) 8

Tipuri abstracte de data si obiecte


! A doua definitie pentru obiecte si clase: " O clasa este o implementare a unui tip de data abstract. Ea defineste atribute si metode care implementeaza structura de date respectiv operatiile tipului de data abstract. " Un obiect este o instanta a unei clase. El este unic determinat de numele sau si defineste o stare reprezentata de valorile atributelor sale la un anumit moment particular.

Dorel Lucanu

Programarea calculatoarelor (C++)

stiva ! tipul de data abstract Stiva " entitati de tip data: liste FIFO " operatii # push() # pop() # top()

Stiva tab[0..MAX-1] virf push() pop() top()

Dorel Lucanu

Programarea calculatoarelor (C++)

10

Stiva.h
#define MAX_STIVA 10 class Stiva { public: Stiva(); ~Stiva(); void push(char); void pop(); char top(); bool este_vida(); private: char tab[MAX_STIVA]; int virf; };

Dorel Lucanu

Programarea calculatoarelor (C++)

11

Stiva.cpp
Stiva::Stiva() { virf = -1; } void Stiva::push(char c) { if (virf == MAX_STIVA-1) throw "Depasire superioara."; tab[++virf] = c; } void Stiva::pop() { if (virf < 0) throw "Depasire inferioara."; virf--; } char Stiva::top() { if (virf < 0) throw "Depasire inferioara."; return tab[virf]; }
Dorel Lucanu Programarea calculatoarelor (C++) 12

Stiva_demo
#include <iostream.h> #include "stiva.h" void main(void) { Stiva S; char c='a'; try { while (true) { S.push(c++); cout << S.top() << endl; } } catch (char *mes_err) { cout << mes_err << endl; } }

Dorel Lucanu

Programarea calculatoarelor (C++)

13

my_string.h

Dorel Lucanu

Programarea calculatoarelor (C++)

class string { public: // Constructori/destructori string(); string(char* new_string); string(const string& new_string); . . . ~string(); // operatii int size() const; const char* c_str() const; friend string operator+ (const string& lhs, const string& rhs); string& operator= (const string& a_string); friend ostream& operator<< (ostream& os, const string& a_string); . . . private: char* char_arr; int string_length; };

14

my_string.h - utilizare
string s1(123); string s2; s2 = string("abc") + s1; s1 = s2 ; string s3(s2); s1 = "armata"; b = (s1 == s2);

STL (Standard Template Library) #include <string> #using namespace std

Dorel Lucanu

Programarea calculatoarelor (C++)

15

Curs 2
! De la C la C++ " comentarii cu // " Conversii de tip (type casting) " intrari/iesiri cu cin >> si respectiv cout << (c2cpp1.cpp, c2cpp10.cpp, c2cpp11.cpp,) " fisiere intrare/iesire (c2cpp10.cpp) " declaratii variabile (c2cpp2.cpp, c2cpp3.cpp) " apel prin referinta (c2cpp4.cpp) " functii care intorc variabile (c2cpp4.cpp) " functii inline (c2cpp5.cpp) " exceptii (c2cpp6.cpp)

Dorel Lucanu

Programarea calculatoarelor (C++)

16

De la C la C++ (-1)
! Conversii de tip (type casting) " in C: int n; float x; x = (float) n; " in C++: int n; float x; x = float(n); ! Intrari iesiri // introducerea unui numar int nr; char s[100]; cout << "Numar>"; cin >> nr; // introducerea unui sir cout << "Sir> "; cin >> s;

Dorel Lucanu

Programarea calculatoarelor (C++)

17

De la C la C++ (0)
! fisiere intrare/iesire // varianta 1 (nu prea OK) char c; ifstream f_inp("c2cpp10.cpp"); ofstream f_out("c2cpp10.cp1"); if (f_out && f_inp) while (f_inp >> c) f_out << c; // varianta 2 (mai fidela) ifstream f_inp("c2cpp10.cpp"); ofstream f_out("c2cpp10.cp2"); if (f_out && f_inp) while (f_inp.get(c)) f_out << c; // varianta 3 fstream f_inp; fstream f_out; f_inp.open("c2cpp11.cpp", ios::in); f_out.open("c2cpp11.cp1", ios::out); if (f_out && f_inp) while (f_inp.get(c)) f_out << c; f_inp.close(); f_out.close();
Dorel Lucanu Programarea calculatoarelor (C++) 18

De la C la C++ (I)
! variabilele se pot declara oriunde int a; a = 10; cout << a << endl; // afiseaza 10 { double a, b = 2.0; a = 3.14 * b; cout << a << endl; // afiseaza 6.28 } a *= 3; cout << a << endl; // afiseaza 30 ! variabile declarate in interiorul unui ciclu for for(int i=0; i<4; i++) { int a = i; a *= 10; cout << a << endl; } cout << i; // OK (sau warning) cout << a; // EROARE

Dorel Lucanu

Programarea calculatoarelor (C++)

19

De la C la C++ (II)
! variabilele globale pot fi accesate chiar daca sint ascunse double a = 10.0; void main(void) { char *a = "zece"; cout << "a local = " << a << endl; cout << "a global = " << ::a << endl; } ! variabile cu mai multe nume (alias-uri) double x = 3.1415927; double& y = x; // y face referire la x y = 23.45; cout << x << endl; // afiseaza 23.45

Dorel Lucanu

Programarea calculatoarelor (C++)

20

De la C la C++ (III)
! apel prin referinta void swap (int& x, int& y) { int aux = x; x = y; y = aux; } ! o functie poate returna o variabila float& var_max(float& x, float& y) { if (x > y) return x; else return y; }

Dorel Lucanu

Programarea calculatoarelor (C++)

21

De la C la C++ (IV)
! daca nu-ti plac pointerii: double *p; p = new double; *p = 5.0; double& x = *p; x *= 2.0; cout << *p << " este acelasi cu " << x << endl; ! functii inline inline double ipot(double a, double b) { return sqrt(a*a + b*b); };

Dorel Lucanu

Programarea calculatoarelor (C++)

22

De la C la C++ (V)
! functii inline (continuare) class Data { public: int zi() { return z; } // ... private: int z, l, a; }; este echivalenta cu class Data { public: int zi(); // ... private: int z, l, a; }; inline int Data::zi() { return z; }
Dorel Lucanu Programarea calculatoarelor (C++) 23

De la C la C++ (VI)
! exceptii int add(int a, int b) { if ((b > 0) && (a > INT_MAX-b)) throw "Depasire superioara"; if ((b < 0) && (a < INT_MIN-b)) throw "Depasire inferioara"; return a+b; } int x,y; cout << "Introduceti x si y: "; cin >> x >> y; try { cout << "Suma este " << add(x, y) << endl; } catch (char *err) { cout << "EROARE: " << err;

Dorel Lucanu

Programarea calculatoarelor (C++)

24

De la C la C++ (VII)
! exceptii (continuare) int nr; cout << "Numar> "; cin >> nr; cout << endl; try { if (nr == 0) throw "zero"; if (nr == 1) throw "unu"; if (nr % 2 == 0) throw "par"; for (int i = 3; i < sqrt(nr); i++) if (nr % i == 0) throw "neprim"; throw "prim"; } catch (char *concluzie) { cout << " Numarul introdus este " << concluzie; cout << endl;

Dorel Lucanu

Programarea calculatoarelor (C++)

25

Curs 3
! De la C la C++ (continuare) " exceptii vs assert() " parametri impliciti " supraincarcarea operatorilor (c2cpp7.cpp, c2cpp9.cpp) " template-uri (c2cpp8.cpp, meniu1.h, contor-m1.h, container.h, container_contor1.cpp) " alocare dinamica (string.h) " Structuri (c2cpp12.cpp)

Dorel Lucanu

Programarea calculatoarelor (C++)

26

De la C la C++ (VII+1)
! exceptii vs assert() void Stiva::push(char c) { if (virf < -1 || virf >= MAX_STIVA) throw ERR:invariant."; . . . } inline void Stiva::check() {
#ifndef NDEBUG

if (virf < -1 || virf >= MAX_STIVA) throw ERR:invariant."; #endif } void Stiva::push(char c) { assert(virf <= -1 && virf<MAX_STIVA); . . . }

Dorel Lucanu

Programarea calculatoarelor (C++)

27

De la C la C++ (VII+2)
! Parametri impliciti int fct(int x=7, int y=9) { return x+y; } void main() { cout << fct() << endl; // 16 cout << fct(2) << endl; // 11 cout << fct(2, 3) << endl; // 5 } ! ce se intimpla daca mai definim o functie fct()? int fct(int x) { return 2*x; } # eroare de compilare
Dorel Lucanu Programarea calculatoarelor (C++) 28

De la C la C++ (VIII)
! supraincarcarea operatorilor struct punct { int x,y; }; punct operator * (int a, punct p) { punct q; q.x = a * p.x; q.y = a * p.y; return q; } bool operator == (punct p, punct q) { return (p.x == q.x && p.y == q.y); } //... a.x = 1; a.y = 2; b = 5 * a; cout << endl << b.x << ", " << b.y << endl; if (a == b) cout << "egal" << endl; else cout << "diferit" << endl;
Dorel Lucanu Programarea calculatoarelor (C++) 29

De la C la C++ (IX)
! supraincarcarea operatorilor (continuare) ostream& operator << (ostream& o, punct p) { o << "(" << p.x << ", " << p.y << ") "; }; //... cout << b << endl; //va scrie (5, 10) ! operatori in string.h String& operator +(const String& a_string); String& operator +=(const String& a_string); String& operator =(const String& a_string); // ... friend ostream& operator<< (ostream& os, const String& a_string); ! Supraincarcarea functiilor void swap(int& x, int& y) { int aux = x; x = y; y = aux; }
Dorel Lucanu Programarea calculatoarelor (C++) 30

De la C la C++ (X)
void swap(double& x, double& y) { tip aux = x; x = y; y = aux; } ! template-uri template <class tip> void swap(tip& x, tip& y) { tip aux = x; x = y; y = aux; } int m = 8, n = 15; swap(m, n); . . . double a = 10.0, b = 20.0; swap(a,b); . . .
Dorel Lucanu Programarea calculatoarelor (C++) 31

De la C la C++ (XI)
! template-uri (continuareI) template <class Obiect> class Meniu { public: //... void set_obiect(Obiect& obiect_nou) { obiect = &obiect_nou; } //... private: //... Obiect *obiect; } class Meniu_Contor : public Meniu<Contor> { //... }

Dorel Lucanu

Programarea calculatoarelor (C++)

32

De la C la C++ (XII)
! template-uri (continuare II) template <class Obiect> class Container { public: // ... protected: Meniu<Obiect> *meniu; Display_Box<Obiect> *displ_box; }; class Container_Contor : public Container<Contor> { // ... };

Dorel Lucanu

Programarea calculatoarelor (C++)

33

De la C la C++ (XIII)
! alocare dinamica class String { public: // Constructori/destructori String() { char_arr = new char[1]; char_arr[0] = '\0'; } String(const char* new_string); . . . ~String() { delete[] char_arr; } . . . } String::String(const char* new_string) { string_length = strlen(new_string); char_arr = new char[string_length + 1]; strcpy(char_arr, new_string); }
Dorel Lucanu Programarea calculatoarelor (C++) 34

De la C la C++ (XIV)
! alocare dinamica (continuare I) String *ps = new String("Sir alocat dinamic."); cout << *ps << endl; delete ps; cout << *ps << endl; String *ps1 = new String("Alt sir alocat dinamic."); cout << *ps << endl; String *psa = new String[5]; for (int i = 0; i<5; i++) { psa[i] = String(i); cout << psa[i] << endl; } delete[] psa;

Dorel Lucanu

Programarea calculatoarelor (C++)

35

De la C la C++ (XV)
! Structuri struct Data { int z, l, a; void init(int o_zi, int o_luna, int un_an); void aduna_an(int n); void aduna_luna(int n); void aduna_zi(int n); }; void Data::init(int o_zi, int o_luna, int un_an) { z = o_zi; l = o_luna; a = un_an; } // ... Data azi; azi.z = 20; azi.aduna_zi(6); cout << azi.z;
Dorel Lucanu Programarea calculatoarelor (C++) 36

Curs 4
! O trecere in revista a POO

"Ierarhii de clase (relatia generalizare/specializare") "Relatii de asociere intre clase "Relatia de compozitie

Dorel Lucanu

Programarea calculatoarelor (C++)

37

Generalizare/specializare I
! Sint un student: " Imi cunosc ID-ul " Imi cunosc numele " Stiu disciplinele pe care le urmez " Pot sa-mi spun ID-ul " Pot sa-mi spun numele " Pot sa ma inscriu la o noua disciplina

Student id nume discUrmate getId() getNume() addDiscUrmata()

Dorel Lucanu

Programarea calculatoarelor (C++)

38

Generalizare/specializare II
! Sint un profesor: " Imi cunosc ID-ul " Imi cunosc numele " Stiu disciplinele pe care le predau " Pot sa-mi spun ID-ul " Pot sa-mi spun numele " Pot sa predau o noua disciplina

Profesor id nume discPredate getId() getNume() addDiscPredata() examineaza()

Dorel Lucanu

Programarea calculatoarelor (C++)

39

Generalizare/specializare III Generalizam


! Sint o persoana: " Imi cunosc ID-ul " Imi cunosc numele " Pot sa-mi spun ID-ul " Pot sa-mi spun numele

Specializam
! Sint un student: " Mostenesc atributele si operatiile de la Persoana " Stiu disciplinele pe care le urmez " Pot sa ma inscriu la o noua disciplina ! Sint un profesor: " Mostenesc atributele si operatiile de la Persoana " Stiu disciplinele pe care le predau " Pot sa predau o noua disciplina
Dorel Lucanu Programarea calculatoarelor (C++) 40

Generalizare/specializare IV

Persoana id nume getId() getNume()

Student discUrmate addDiscUrmata()

Profesor discPredate addDiscPredata() examineaza()

Dorel Lucanu

Programarea calculatoarelor (C++)

41

Generalizare/specializare in C++
class Persoana { public: Persoana(string = "", string = ""); ~Persoana(); string getNume() const; string getId() const; private: string id, nume; };

class Student : public Persoana { public: Student(string="", string=""); ~Student(); void addDiscUrmata(Disciplina*); private: Disciplina *discUrmate[MAX]; int nrDiscUrmate; };

class Profesor : public Persoana { . . . };


Dorel Lucanu Programarea calculatoarelor (C++) 42

Relatii de asociere intre clase

Dorel Lucanu

-urmeaza Disciplina * 1 * * 1

-predataDe

-titular Profesor

Student

Programarea calculatoarelor (C++)

* Examen *

43

Relatii de asociere in C++


class Disciplina { public: . . . void setTitular(Profesor*); Profesor* getTitular() const; . . . private: . . . Profesor* titular; };

class Examen { public: . . . void addStudent(Student*); Disciplina* getDisc() const; private: Disciplina* disc; struct { Student* stud; int nota; } exam[MAX_nrStudEx]; };
Dorel Lucanu Programarea calculatoarelor (C++) 44

Relatia de compozitie

Dorel Lucanu

1 Facultate 1 1 1

Programarea calculatoarelor (C++)

1..* 1..* 1..* Profesor

0..* Examen

Student

Disciplina

45

Relatii de compozitie in C++


class Facultate { public: Facultate(int=0, int=0, int=0, int=0); . . . private: Student* stud; int nrStud; int MAX_nrStud; . . . };

Facultate::Facultate(int INI_stud, . . .) { nrStud = 0; MAX_nrStud = INI_stud; stud = new Student[MAX_nrStud]; if (stud == NULL) throw "Facultate: mem. heap insuf."; . . . }

Dorel Lucanu

Programarea calculatoarelor (C++)

46

Curs 5
! O trecere in revista a POO (continuare) " Comunicarea intre obiecte " Polimorfism " Clase parametrizate

Dorel Lucanu

Programarea calculatoarelor (C++)

47

Comunicarea intre obiecte Sint facultatea FII comunic profesorului P sa examineze studentii inscrisi la examenul E. Sint profesorul P examinez studentii si comunic examenului E notele acordate. Sint facultatea FII: comunic examenului E sa afiseze notele
examineaza() fii : sco::Facultate
az te lis

: sco::Profesor

: sco::Examen

Dorel Lucanu

Programarea calculatoarelor (C++)

se tN ot a( )

aN ) e( ot

mesaje

48

Mesaje in C++

void Facultate::examineaza() { . . . prof[iProf].examineaza(ex[iEx]); }; void Profesor::examineaza(Examen& unEx) const { . . . for (int i=0; i < unEx.nrStud; i++) { . . . unEx.setNota(unEx.exam[i].stud, notaStud); } } void Examen::setNota(Student* unStud, int oNota) { . . . exam[i].nota = oNota; };

Dorel Lucanu

Programarea calculatoarelor (C++)

49

Sumar ! Un obiect are abilitatea: "de a se crea "de a se distruge "de a-si regasi datele (valorile atributelor) "de a-si actualiza datele (valorile atributelor) "de a comunica cu alte obiecte prin transmiterea de mesaje

Dorel Lucanu

Programarea calculatoarelor (C++)

50

Polimorfism::suprascriere I
class Persoana { . . . void semneaza(); }; class Student : public Persoana { . . . void semneaza(); }; class Profesor : public Persoana { . . . void semneaza(); }; void Persoana::semneaza() { cout << getNume() << endl; } void Student::semneaza() { cout << "Student " << getNume() << endl; } void Profesor::semneaza() { cout << "Profesor " << getNume() << endl; }
Dorel Lucanu Programarea calculatoarelor (C++) 51

Polimorfism:: suprascriere II
Persoana p("0000", "Strainu Stefan"); Student st("1111", "Ionescu Ion"); Profesor pr("2222", "Popescu Petru"); p.semneaza(); st.semneaza(); pr.semneaza();

Strainu Stefan Student Ionescu Ion Profesor Popescu Petru

Dorel Lucanu

Programarea calculatoarelor (C++)

52

Polimorfism:: suprascriere III

void semneaza(Persoana* p) { p->semneaza(); }; semneaza(&p); semneaza(&st); semneaza(&pr);

Strainu Stefan Ionescu Ion Popescu Petru

Dorel Lucanu

Programarea calculatoarelor (C++)

53

Polimorfism::functii virtuale
class Persoana { . . . virtual void semneaza(); }; class Student : public Persoana { . . . virtual void semneaza(); }; class Profesor : public Persoana { . . . virtual void semneaza(); };

semneaza(&p); semneaza(&st); semneaza(&pr);

Strainu Stefan Student Ionescu Ion Profesor Popescu Petru


Dorel Lucanu Programarea calculatoarelor (C++) 54

Parametrizare I (cell.h)
template <class Elt> class Cell { public: Cell(); ~Cell(); Elt getVal(); setVal(Elt); private: Elt* val; }; template <class Elt> Cell<Elt>::Cell() { val = new Elt; } template <class Elt> Cell<Elt>::~Cell() { delete val; } template <class Elt> Elt Cell<Elt>::getVal() { return *val; } . . .
Dorel Lucanu Programarea calculatoarelor (C++) 55

Parametrizare II (demo.cpp)

Cell<int> x; x.setVal(100); Cell<char> c; c.setVal('A'); cout << "x = " << x.getVal(); cout << "c = " << c.getVal();

Dorel Lucanu

Programarea calculatoarelor (C++)

56

Curs 6
! Clase (avansat) " definitie " exemple (data.h, data.cpp, data_demo.cpp, llin.h, llin.cpp, llin_demo.cpp) " declaratie " date membre " functii membre " pointerul this " prietenii unei clase " constructori si operatorul new " destructori si operatorul delete

Dorel Lucanu

Programarea calculatoarelor (C++)

57

Clase
! definitie: " o clasa in C++ are asociate 4 tipuri de elemente: o colectie de date membre (atribute) o colectie de functii membre (metode) nivele de acces ale programului (public, private, ...) un nume " declaratie <decl_clasa> ::= class <nume_clasa> { <corp> } " Implentarea functiilor <tip> <nume_clasa> ::= <nume_functie>(<param>) {<definitie_functie} ! date membre " sint declarate ca variabile ! ascunderea informatiei class nume_clasa { public: ... private: ... } ! obiecte " sint declarate ca variabile <nume_clasa> <lista_nume_obiecte>; ! exemple: Data, LLin
Dorel Lucanu Programarea calculatoarelor (C++) 58

Clasa Data

(data.h)

class Data { public: Data(int o_zi = 1, int o_luna = 1, int un_an = 1900); ~Data() { } void aduna_zi(int n); void aduna_luna(int n); void aduna_an(int n); Data& operator ++(int); // postfix Data& operator ++(); // prefix void set_zi(int zi_noua); void set_luna(int ); void set_an(int an_nou); int get_zi() const; int get_luna() const; int get_an() const; friend ostream& operator << (ostream&, Data&); private: int zi, luna, an; };
Dorel Lucanu Programarea calculatoarelor (C++) 59

Clasa Data v. simpla (data.h)


class Data { public: Data(int o_zi = 1, int o_luna = 1, int un_an = 1900); ~Data() { } void aduna_zi(int n); void aduna_luna(int n); void aduna_an(int n); void set_zi(int zi_noua); void set_luna(int ); void set_an(int an_nou); int get_zi() const; int get_luna() const; int get_an() const; private: int zi, luna, an; };

Dorel Lucanu

Programarea calculatoarelor (C++)

60

Clasa LLin (llin.h)


class NodLLin { public: friend class LLin; private: Elt elt; NodLLin *pred, *succ; }; class LLin { public: // constructori/destructori (manageri) LLin(); ~LLin(); // operatii bool esteVida(); void insereaza(int k, Elt un_elt); void eliminaDeLaK(int k); void elimina(Elt un_elt); void parcurge(void viziteaza(Elt)); Elt citeste(int k) const; int poz(Elt un_elt) const; int lung() const; private: NodLLin *prim; void remove(); };
Dorel Lucanu Programarea calculatoarelor (C++) 61

Clasa Data
#include "data.h"

(data.cpp)

Data::Data(int o_zi, int o_luna, int un_an) { zi = o_zi; luna = o_luna; an = un_an; } void Data::aduna_zi(int n) { // trebuie implementat }

void Data::aduna_an(int n) { an += n; }

Dorel Lucanu

Programarea calculatoarelor (C++)

62

Clasa Data

(data_demo.cpp)

Data azi(zi_curenta(), luna_curenta(), an_curent()); cout << azi << endl; int zz = azi.get_zi(); azi.set_zi(29); azi++; cout << azi.get_zi() << endl; azi.aduna_luna(15); cout << azi.get_luna() << ' ' << azi.get_an() << endl;

int zi_curenta() { struct tm *tp; //struct tm este definit in <time.h> time_t acum; //time_t este definit in <time.h> acum = time(NULL); tp = localtime(&acum); return tp->tm_mday; }

Dorel Lucanu

Programarea calculatoarelor (C++)

63

Clase (continuare I)
! functii membre " functii manager (constructori, destructori) Data::Data() Data::~Data() " implementori (implementeaza operatiile clasei) Data::aduna_an() Data::aduna_zi() " functii ajutatoare Llin::remove() " functii de acces Data::set_zi() Data::get_zi() ! functii membre const int Data::get_zi() const {...} int Data::get_luna() const {...} " supraincarcarea functiilor const cu functii nonconst int Data::get_zi() {...} ... const Data oZiConst(12,3,2001); Data oZi(1,4,2000); ... oZiConst.get_zi(); oZi.get_zi();
Dorel Lucanu Programarea calculatoarelor (C++) 64

Clase (continuare II)


! pointerul implicit this " despre implementare: exista o singura instanta pt fiecare functie membru: get_zi_Data (Data *this) { return this->z; } azi.get_zi(); // este echivalent cu get_zi_Data(&azi); ieri.get_zi(); // este echivalent cu get_zi_Data(&ieri); " utilizare Data& Data::operator ++() { this->zi++; return (*this); }
Dorel Lucanu Programarea calculatoarelor (C++) 65

Clase (continuare III)


! prietenii unei clase class Data { //... friend ostream& operator << (ostream&, Data&); //... } //... ostream& operator <<(ostream& o,Data& d) { o << d.zi << ' ' << d.luna << ' ' << d.an; return o; } //... class NodLLin { Elt elt; Nod *pred, *succ; public: friend LLin; };
Dorel Lucanu Programarea calculatoarelor (C++) 66

Clase (continuare IV)


! constructori class Data { public: Data(); Data(int, int, int); Data(char*); //... private: int zi, luna, an; char *data_ca_sir; } " declaratia Data d(12, 12, 2000); este echivalenta cu Data d = Data(12, 12, 2000); ! constructorii si operatorul new Data *pdata = new Data(12, 12, 1999); ! destructori ~Data() { delete[] data_ca_sir; } " destructorii si operatorul delete delete pdata; //invoca Data::~Data()

Dorel Lucanu

Programarea calculatoarelor (C++)

67

Curs 7
! Clase (continuare) " membri statici " tipul unui membru " spatiul de nume si domeniul de vizibilitate ale unei clase " union " obiectele ca membre ale unei clase " functii membre care intorc referinte la date membre private?

Dorel Lucanu

Programarea calculatoarelor (C++)

68

Clase (continuare V)
! membri statici: numararea obiectelor create #include <iostream.h> class A { public: A() { nr_instante++; } ~A() { } int get_nr_inst() { return nr_instante; } private: static int nr_instante; }; int A::nr_instante = 0; void main() { A a; A b; cout << a.get_nr_inst() << endl; cout << b.get_nr_inst() << endl; }

Dorel Lucanu

Programarea calculatoarelor (C++)

69

Clase (continuare VI)


! tipul unui membru al clasei int (*fint)(); fint = zi_curenta; fint = Data::get_zi;

// OK. // eroare

$ de ce eroare? # un pointer la o functie membra trebuie sa se potriveasca in trei elemente: numarul si tipurile argumentelor tipul valorii returnate tipul clasei a carei membra este ! pointer la membrul unei clase int (Data::*fint)(); fint = Data::get_zi;

// OK!

Dorel Lucanu

Programarea calculatoarelor (C++)

70

Clase (continuare VII)


! spatiul de nume si domeniul de vizibilitate ale unei clase " fiecare clasa isi are propriul spatiu de nume double zi; class Data { public: //... int get_zi() {return zi;} private: int zi, luna, an; }//... void Data::aduna_luna(int n) { int luna = Data::luna + n; // nerecomandat } class A { public: static int doi() { return 2; } } //... A::doi(); // OK! Data::aduna_luna(5); // nu-i OK!
Dorel Lucanu Programarea calculatoarelor (C++) 71

Clase (continuare VII+1)


! spatiul de nume al unei clase ... (continuare I) class LLin { public: class Nod { public: void set_elt(Elt un_elt); //. . . private: Elt elt; Nod *leg; }; void insereaza(int, Elt); // ... private: Nod *prim; //... }; //. . . void LLin::insereaza(int k, Elt un_e) { Nod *p = new Nod; p->elt = un_elt; //eroare p->set_elt(un_elt); //OK //... }; void LLin::Nod::set_elt(Elt un_elt) {...} //... LLin::Nod n;
Dorel Lucanu Programarea calculatoarelor (C++) 72

Clase (continuare VIII)


! spatiul de nume al unei clase ... (continuare II) class LLin { public: void insereaza(int, Elt); // ... private: class Nod { public: //. . . private: //... }; Nod *prim; }; //. . . // in rest la fel, dar LLin::Nod n; //eroare

Dorel Lucanu

Programarea calculatoarelor (C++)

73

Clase (continuare IX)


! union union Elt { public: Elt(); ~Elt(); void set_operator(char op_nou) char get_operator(); . . . private: char oprtr; int oprnd; }; este echivalenta cu class Elt { public: Elt(); . . . private: union { char oprtr; int oprnd; }; };
Dorel Lucanu Programarea calculatoarelor (C++) 74

Clase (continuare X)
! obiectele ca membre ale unei clase class Student { public: Student(char*); Student(char*, int); ~Student() {} private: String nume; int virsta; }; " initializarea obiectelor membre Student::Student(char *un_nume, int o_virsta) : nume(un_nume), virsta(o_virsta) { //nimic } " ordinea apelarii constructorilor Student(Ionescu,22); //virsta = 22 //String::String(char*) //Student::Student(char*, int)
Dorel Lucanu Programarea calculatoarelor (C++) 75

Clase (continuare XI)


" alt exemplu class Cuvint { public: Cuvint(const char*, int=0); private: String cuv; int nr_ap; }; Cuvint::Cuvint(const char* un_s, int un_nr) : cuv(un_s), nr_ap(un_nr) { //nimic } class Sinonim { public: Sinonim(const char*, const char*); private: String sin; Cuvint cuv; }; Sinonim::Sinonim(const char* un_cuv, const char* un_sin) : cuv(un_cuv), sin(un_sin) { //nimic } Sinonim s("sir", "string");
//String(string), String(sir), Cuvint(...), Sinonim(...) Dorel Lucanu Programarea calculatoarelor (C++) 76

Clase (continuare XII)


! atentie la functii membre care intorc referinte la date membre private! class A { public: A(int x = 0): elt(x) { } int& get_elt() { return elt; } private: int elt; }; void main() { A a(5); (a.get_elt())++; cout << a.get_elt() << endl; }

Dorel Lucanu

Programarea calculatoarelor (C++)

77

Curs 8
! Clase (continuare) " initializarea membru cu membru, constructorul de copiere X::X(const X&) " operatorul de atribuire X& X::operator=(const X&) ! Clase parametrizate " stive parametrizate " cozi parametrizate " liste parametrizate " prieteni si clase parametrizate

Dorel Lucanu

Programarea calculatoarelor (C++)

78

Clase (continuare XII)


! Initializarea membru cu membru " cazul cind nu exista alocare dinamica Data azi(4,4,2000); Data data_n = azi; #este apelat automat un constructor X::X(const X&) #in cazul clasei Data acesta este echivalent cu: Data::Data(const Data& d) { zi = d.zi; luna = d.luna; an = d.luna; }

Dorel Lucanu

Programarea calculatoarelor (C++)

79

Clase (continuare XIII)


" cazul cind exista alocare dinamica String s(Programare C++); String curs = s; #trebuie definit explicit constructorul: String::String(const String& new_string) { string_length = new_string.size(); char_arr = new char[string_length + 1]; strcpy(char_arr, new_string.char_arr); }

Dorel Lucanu

Programarea calculatoarelor (C++)

80

Clase (continuare XIV)


" cazul obiectelor membre Student st1(Ionescu,22); Student st2 = st1; //... Student::Student(const& Student un_st) : nume(un_st.nume) { virsta = un_st.virsta; } # nume = un_st.nume; // nu-i OK! ! X::operator=(const X&) Data azi(4,4,2000); Data ieri; ieri = azi; # o instanta a operatorului X& X::operator=(const X&) este apelata automat: Data& Data::operator=(const Data& d) { zi = d.zi; luna = d.luna; an = d.an; }
Dorel Lucanu Programarea calculatoarelor (C++) 81

Clase (continuare XV)


" X& X::operator=(const X&) (continuare) #in cazul clasei String avem alocare dinamica si acest operator trebuie redefinit String& String::operator= (const String& a_string) { if ((*this) != a_string ) { if ( string_length != a_string.size()) { delete[] char_arr; string_length = a_string.size(); char_arr = new char[string_length+1]; } strcpy(char_arr, (char*) a_string ); } return (*this); }

Dorel Lucanu

Programarea calculatoarelor (C++)

82

Clase (continuare XVI)


! operatorii [] si () (iterator) class String { public: //... char& operator[] (int); char operator() (); private: int ind_curent; //... } inline char& String::operator [](int i) { assert(i >= 0 && i <= string_length); return char_arr[ i ]; } char String::operator () { char c = char_arr[ind_curent] ind_curent = ind_curent > string_length ? 0 : ind_curent+1; return c; }
Dorel Lucanu Programarea calculatoarelor (C++) 83

Clase parametrizate I
! stive parametrizate " reprezentarea simplu inlantuita template <class Elt> class NodStiva { public: friend class Stiva<Elt>; private: Elt elt; NodStiva *leg; } template <class Elt> class Stiva { public: Stiva(); ~Stiva(); void push(Elt); void pop(); Elt top(); private: NodStiva<Elt> *virf; };
Dorel Lucanu Programarea calculatoarelor (C++) 84

Clase parametrizate II
template <class Elt> void Stiva<Elt>::push(Elt un_e) { NodStiva<Elt> *p = new NodStiva<Elt>; assert (p != 0); p->elt = un_e; p->leg = virf; virf = p; } template <class Elt> Elt Stiva<Elt>::top() { return virf->elt; } //...

Dorel Lucanu

Programarea calculatoarelor (C++)

85

Clase parametrizate III


" exemplu de utilizare Stiva<char> st; st.push(a); cout << st.top(); " reprezentarea cu tablouri template <class Elt, int MAX_STIVA> class Stiva { public: Stiva(); ~Stiva(); void push(Elt); void pop(); Elt top(); private: Elt *ptab; int virf; };

Dorel Lucanu

Programarea calculatoarelor (C++)

86

Clase parametrizate IV
template <class Elt, int MAX_STIVA> Stiva<Elt, MAX_STIVA>::Stiva() { ptab = new Elt[MAX_STIVA]; virf = -1; } ! prieteni si clase parametrizate " prieteni neparametrizati template <class Elt> class Nod { Elt elt; //... friend void a(); }

Dorel Lucanu

Programarea calculatoarelor (C++)

87

Clase parametrizate V
" prieteni parametrizati legati template <class Elt> class NodStiva { //... friend class Stiva<Elt>; } " prieteni parametrizati nelegati template <class Elt> class Nod { Elt elt; //... template <class T> friend void a<T>(); }

Dorel Lucanu

Programarea calculatoarelor (C++)

88

Curs 9
! Relatia de mostenire (derivare) " Exemple: most.h, most_demo.cpp " definirea mostenirii " accesul la membrii mosteniti " initializarea bazei de clasa " tipuri de mosteniri " conversii standard " ordinea de initializare sub mostenire " copiere si atribuire sub mostenire

Dorel Lucanu

Programarea calculatoarelor (C++)

89

Ierarhia RxR

RxR x : float y : float setX() setY() getX() getY() modul()

Complex PctPlan transl() mutaLa() conj() operator+() operator*() operator-() RxRx R z : float setZ() getY()

PlanComplex phi() rho()

PctSpatiu mutaLa() transl()

Dorel Lucanu

Programarea calculatoarelor (C++)

90

class RxR { protected: . . . public: . . . }; class PctPlan : public RxR { public: . . . }; class Complex : public RxR { public: . . . }; class RxRxR : public RxR { protected: float z; public: . . . }; class PlanComplex : public PctPlan, public Complex {. . .}; class PctSpatiu : public RxRxR { public: . . . };
Dorel Lucanu Programarea calculatoarelor (C++) 91

Mostenire (continuare I)
! accesul la membrii mosteniti PctSpatiu p(10.0,10.0,10.0); p.setX(20.0); a = p.getZ(); b = p.modul(); // RxRxR::modul() c = p.RxR::modul(); ! initializarea clasei de baza RxRxR(float un_x, float un_y, float un_z ) : RxR(un_x, \ \ \ un_y), z(un_z) {}

# o clasa de baza care nu declara constructor sau declara un constructor fara argumente nu necesita initializarea explicita # constructorii de baza sint invocati inaintea celor derivati ! nivele de protectie a membrilor: " public: cunoscut de toata lumea " protected: cunoscut de clasa proprietara si de clasele mostenitoare " private: cunoscut numai de clasa proprietara

Dorel Lucanu

Programarea calculatoarelor (C++)

92

Mostenire (continuare II)


! tipuri de mostenire " public class clasaDerivata : public clasaBaza {...} # ce e public in clasa de baza ramine public in clasa derivata # ce e protected in clasa de baza ramine protected in clasa derivata " protected class clasaDerivata : protected clasaBaza {...} # ce e public in clasa de baza devine protected in clasa derivata # ce e protected in clasa de baza ramine protected in clasa derivata " private class clasaDerivata : private clasaBaza {...} # ce e public in clasa de baza devine private in clasa derivata # ce e protected in clasa de baza devine private in clasa derivata
Dorel Lucanu Programarea calculatoarelor (C++) 93

Mostenire (continuare III)


! conversii standard (cazul mostenirii publice) # un obiect derivat poate fi convertit implicit la un obiect public de baza # o adresa a unui obiect derivat poate fi convertita implicit la o adresa publica a unui obiect de baza # un pointer la un obiect derivat poate fi convertit implicit la un pointer public la un obiect de baza float distPlanXY(RxR p, RxR q) { //... } //... PctPlan a,b; d1 = disPlanXY(a, b); PctSpatiu u,v; d2 = disPlanXY(u, v);

Dorel Lucanu

Programarea calculatoarelor (C++)

94

Mostenire (continuare IV)


! ordinea de initializare sub mostenire RxR(float un_x = 0, float un_y = 0) : x(un_x), y(un_y) {} RxRxR(float un_x, float un_y, float un_z) : RxR(un_x, un_y), z(un_z) {} PctSpatiu(float un_x, float un_y, float un_z) : RxRxR(un_x, un_y, un_z) {} //... PctSpatiu P(10,10,10); // ordinea de apelare a constructorilor: // x(10); y(10); // RxR(10,10); z(10) // RxRxR(10,10,10) // PctSpatiu(10,10,10) Regula: # constructorii de baza (stramosii) in ordinea declararii lor in ierarhie # constructorii obiectelor membre in ordinea declararii # constructorul clasei derivate

Dorel Lucanu

Programarea calculatoarelor (C++)

95

Mostenire (continuare V)
! ordinea de copiere sub mostenire PctSpatiu Q = P; // se apeleaza constructorii in ordine // RxR(const RxR&); RxRxR(const RxRxR&) // PctSpatiu(const PctSpatiu&) RxR A; A = P; // se apeleaza operatorul de atribuire // RxR::operator =(const RxR&) # Atentie la pointeri; in cazul acesta exista constructori X(const X&) si X& X::operator=(const X&) definiti expliciti. # Se disting situatiile: Clasa Clasa de baza derivata implicit implicit explicit implicit explicit explicit explicit Ordinea de apelare !constr. definit de clasa de baza !constr. definit de clasa derivata !constr. definit de clasa derivata !revine constr. clasei derivate responsabilitatea de a apela constr clasei de baza
Programarea calculatoarelor (C++) 96

Dorel Lucanu

Curs 10
! Clase de baza virtuale (mostv.h, mostv_demo.cpp) ! Derivare si parametrizare (lista.h) ! Functii virtuale " problema " o posibila solutie (nerecomandata) (most1.h, most1dem.cpp) " declararea functiilor virtuale (most2.h, most2dem.cpp) " functii virtuale pure " o alta posibila ierarhie de liste? LLinOrd : public Llin ! Glosar termeni POO

Dorel Lucanu

Programarea calculatoarelor (C++)

97

Clase de baza virtuale

Rx R

Rx R

Pc tP lan

C om plex

P lanC om plex

Rx R

P c t P lan

C om plex

P lanC om plex

Dorel Lucanu

Programarea calculatoarelor (C++)

98

Clase de baza virtuale (continuare)


class PctPlan : virtual public RxR {...}; class Complex : virtual public RxR {...}; class PlanComplex : public PctPlan, public Complex {...}; PlanComplex::PlanComplex(float un_x, float un_y) : PctPlan(un_x, un_y), Complex(un_x, un_y) { // nimic } # atentie! se apeleaza totdeauna constructorul implicit al clasei de baza virtuale PlanComplex pc(5, 5); cout << pc.modul() << endl; // va afisa 0!!! PlanComplex pc2; pc2.setX(5); pc2.setY(5); cout << pc2.modul() << endl; // va afisa 7.07107!!!
Dorel Lucanu Programarea calculatoarelor (C++) 99

Derivare si parametrizare

Elt List a eliminaDeLaK() citeste() parcurge() lung()

Elt LLin insereaza() elimina() poz()

Elt LLinOrd insereaza() elimina() poz()

Dorel Lucanu

Programarea calculatoarelor (C++)

100

Derivare si parametrizare (continuare I)


template <class Elt> class Lista; //decl forward template <class Elt> class LLin; //decl forward template <class Elt> class LLinOrd; //decl forward template <class Elt> class NodLista { Elt elt; NodLista *leg; public: friend class Lista<Elt>; friend class LLin<Elt>; friend class LLinOrd<Elt>; };

Dorel Lucanu

Programarea calculatoarelor (C++)

101

Derivare si parametrizare (continuare II)


template <class Elt> class Lista { public: Lista(); ~Lista(); void eliminaDeLaK(int k); void parcurge(void viziteaza(Elt&)); int lung() const; protected: NodLista<Elt> *prim; void remove(); int nr_elem; }; template <class Elt> class LLin : public Lista<Elt> { public: LLin() : Lista<Elt>() {} void insereaza(int k, Elt& un_elt); void elimina(Elt& un_elt); Elt& citeste(int k) const; int poz(Elt& un_elt) const; };
Dorel Lucanu Programarea calculatoarelor (C++) 102

Derivare si parametrizare (continuare III)


template <class Elt> class LLinOrd : public Lista<Elt> { public: LLinOrd() : Lista<Elt>() {} void insereaza(Elt& un_elt); void elimina(Elt& un_elt); Elt& citeste(int k) const; int poz(Elt& un_elt) const; };

Dorel Lucanu

Programarea calculatoarelor (C++)

103

Functii virtuale
! problema float f(RxR& a) { return a.modul(); } PctSpatiu P(10,10,10); RxR A = P; cout << f(P) << ", " << f(A) << endl; //afiseaza acelasi lucru 14.14... ! o posibila solutie enum tip { rXr, rXrXr }; class RxR { //... tip isA() const {return rXr;} } class RxRxR { //... tip isA() const {return rXrXr;} }

Dorel Lucanu

Programarea calculatoarelor (C++)

104

Functii virtuale (continuare I)


float f(RxR *pa) { switch (pa->isA()) { case rXrXr: return ((RxR *)pa)->modul(); case rXr: return ((RxRxR *)pa)->modul(); } return 0.0; } ! definirea functiilor virtuale class RxR { //... virtual float modul(); } class RxRxR { //... virtual float modul(); } cout << f(P) << ", " << f(A) << endl; //afiseaza OK.
Dorel Lucanu Programarea calculatoarelor (C++) 105

Functii virtuale (continuare II)


! functii virtuale pure class Lista { // ... virtual int poz(Elt&) = 0; //fct. virtuala pura } class LLin : public Lista { // ... virtual int poz(Elt&); } class LLinOrd : public Lista { // ... virtual int poz(Elt&); } ! o alta posibila ierarhie de liste? template <class Elt> class LLinOrd : public LLin<Elt> { //... }

Dorel Lucanu

Programarea calculatoarelor (C++)

106

Glosar POO

Dorel Lucanu

Programarea calculatoarelor (C++)

107

Curs 11
! Biblioteca standard C++ " ce include " Exemple: siruri (stdlib1.cpp) vectori (stdlib2.cpp) liste (stdlib3.cpp) tablouri asociative (stdlib4.cpp) iteratori algoritmi STL framework

Dorel Lucanu

Programarea calculatoarelor (C++)

108

Biblioteca standard
! ce contine: " siruri <string> <cstring> <cstdlib> etc " containeri <vector> <list> <queue> <stack> <map> etc " iteratori <iterator> " algoritmi <algorithm> <cstdlib> " intrari/iesiri <iostream> <istream> etc " etc
Dorel Lucanu Programarea calculatoarelor (C++) 109

Biblioteca standard (continuare I)


! siruri (stdlib1.cpp) #include <string> #include <iostream> using namespace std; int main() { string s("Un text simplu."); string tag("$tag$"); s.insert(8, tag + ' '); cout << s.c_str() << endl; int start = s.find(tag); cout << start << endl; cout << tag.size() << endl; s.replace(start, tag.size(), "foarte"); cout << s.c_str() << endl; return 0; }

Dorel Lucanu

Programarea calculatoarelor (C++)

110

Biblioteca standard (continuare II)


! container " definitie: un obiect care contine alte obiecte " exemple <vector> <list> <deque> <queue> <stack> <map> <set> <bitset> ! iterator " definitie: sint utilizati pentru a naviga prin containeri, fara sa stim ce tip de data este utilizat pentru memorarea obiectelor " concepte cheie: elementul curent la care face referire (reprezentat de * si ->) elementul urmator (reprezentat de ++) egalitate (reprezentata de ==

Dorel Lucanu

Programarea calculatoarelor (C++)

111

Biblioteca standard (continuare III)


! vectori (stdlib2.cpp) #include <vector> #include <string> #include <iostream> using namespace std; struct Intrare { string nume; long nr; }; vector<Intrare> agTel(1000); int main() { agTel[0].nume = "Ionescu"; agTel[0].nr = 123456; . . . agTel[10].nume = "Popescu"; agTel[10].nr = 654321; . . . vector<Intrare> copie = agTel; cout << copie[10].nume << endl; . . . }
Dorel Lucanu Programarea calculatoarelor (C++) 112

Biblioteca standard (continuare IV)


! liste (stdlib3.cpp) #include <list> . . . class Intrare { public: Intrare(char *un_s, long un_n); string getNume() const; long getNr(); private: string nume; long nr; }; list<Intrare> agTel; . . . Intrare x("Ionescu", 123456); agTel.push_front(x); Intrare y("Popescu", 654321); agTel.push_back(y); . . . typedef list<Intrare>::const_iterator LI; for (LI i=agTel.begin(); i!=agTel.end(); ++i) cout << (*i).getNume() << (*i).getNr();
Dorel Lucanu Programarea calculatoarelor (C++) 113

Biblioteca standard (continuare V)


! tablouri asociative (stdlib4.cpp) #include <map> #include <string> #include <iostream> using namespace std; map<string, long> agTel;

. . . agTel["Ionescu"] = 123456; agTel["Popescu"] = 654321; . . . typedef \ map<string, long>::const_iterator LI; for (LI p = agTel.begin(); \ p != agTel.end(); ++p) cout << p->first << ' ' << p->second; . . . cout << agTel["Popescu"] << endl; cout << agTel["Ionescu"] << endl;

Dorel Lucanu

Programarea calculatoarelor (C++)

114

Biblioteca standard (continuare VI)


! algoritm " definitie (in STL): un set de template-uri care actioneaza asupra secventelor de elemente " exemple for_each() find() find_if() count() count_if() replace() replace_if() copy() unique_copy() sort() equal_range() merge()

Dorel Lucanu

Programarea calculatoarelor (C++)

115

Biblioteca standard (continuare VII)


! algoritmi (stdlib5.cpp) list<string> agTel; int bad(const string& s) { return isdigit(s[0]); } . . . agTel.push_front("Ionescu"); agTel.push_front("Popescu"); agTel.push_back ("Cotescu"); agTel.push_back ("Popescu"); agTel.push_front ("1Popescu"); // cauta dupa valoare q = find(agTel.begin(),agTel.end(), "Ionescu"); // cauta dupa criteriu q = find_if(agTel.begin(), agTel.end(), bad); // sterge elementul gasit (daca e cazul) if (q != NULL) { agTel.erase(q); } // sorteaza agTel.sort(); // creza o copie numai cu unicate list<string> copie; unique_copy(agTel.begin(), agTel.end(), \ back_inserter(copie)); agTel = copie;
Dorel Lucanu Programarea calculatoarelor (C++) 116

STL (continuare VIII)


! tablouri asociative: inserare, cautare, stergere (stdlib4.cpp) map<string, long> agTel;

agTel["Ionescu"] = 123456; . . . agTel.insert(agTel.end(), \ make_pair(string("Zorzonel"), \ 123543)); typedef map<string, long>::iterator MI; MI q = agTel.find("Popescu"); if ( q == agTel.end()) cout << "Nu este in carte." << endl; else agTel.erase(q);

Dorel Lucanu

Programarea calculatoarelor (C++)

117

STL (continuare IX)


! tablouri asociative cu chei multiple multimap<string, long> agTel; int main(void) { agTel.insert(agTel.end(), make_pair("Ionescu", 123543)); agTel.insert(agTel.end(), make_pair("Popescu", 123543)); agTel.insert(agTel.end(), make_pair("Popescu", 223543)); agTel.insert(agTel.end(), make_pair("Popescu", 323543)); //... agTel.erase("Popescu"); //sterge toti Popestii //... q = agTel.find("Popescu"); if ( q != agTel.end()) agTel.erase(q); // sterge numai primul Popescu

Dorel Lucanu

Programarea calculatoarelor (C++)

118

STL (continuare X)
! tablouri asociative cu chei multiple si valoare structurata class Info { public: Info(); Info(string o_adr, long un_nr); string getAdr() const; void setAdr(string o_adr); long getNr() const; void setNr(long un_nr); private: string adr; long nr; }; multimap<string, Info> agTel; //... agTel.insert(agTel.end(), make_pair("Ionescu", Info("Merilor 6", 123456))); //... cout << p->second.getAdr();

Dorel Lucanu

Programarea calculatoarelor (C++)

119

Curs 12
! POO :: Studiu de caz:: Concurs de gimnastica (clasam.cpp) " problema " identificarea claselor " identificarea atributelor si operatiilor " modelarea relatiilor dintre clase " comunicarea intre obiecte " descriere in C++

Dorel Lucanu

Programarea calculatoarelor (C++)

120

POO: Concursul de gimnastica (I)


! Problema " obiectiv: simularea sistemului de notare intr-un concurs de gimnastica " descriere: La un concurs de gimnastica participa NR gimnasti. Fiecare gimnast primeste note de la un juriu format din 6 arbitri. La sfirsitul concursului se stabileste un clasament cu gimnastii in ordinea descrescatoare a mediilor. Pentru simplitate se va considear o singura proba. ! determinarea claselor: Concurs, Gimnast, Juriu, Arbitru, Clasament ! determinarea atributelor si operatiilor: " Sint un gimnast: imi cunosc numele imi cunosc tara imi cunosc numarul de ordine imi cunosc notele pe care le primesc stiu sa calculez media " Sint un arbitru: imi cunosc numele imi cunosc tara cind mi se cere dau nota unui gimnast
Dorel Lucanu Programarea calculatoarelor (C++) 121

POO: Concursul de gimnastica (II)


" Sint un juriu: am 6 mese si la fiecare masa este un arbitru pot stabili componenta cind mi se cere sa dau note pentru un jucator, cer la rindul meu fiecarui arbitru sa dea nota " Sint un clasament cunosc gimnastii pot stabili componenta stiu sa-i planific stiu sa-i clasific stiu sa-i afisez " Sint un concurs cunosc juriul (si deci arbitrii) cunosc clasamentul (si deci gimnastii si ordinea de evolutie) stiu ordinea in care se executa activitatile ! relatiile dintre clase Gimnast si Arbitru fac obiectul unei relatii de generalizare/specializare

Dorel Lucanu

Programarea calculatoarelor (C++)

122

POO: Concursul de gimnastica (III)

Persoana nume tara getNume() setNume() getTara() setTara() citeste()

Gimnast
nota[] nrOrd media() setNote() setNota() setNrOrd() getNrOrd()

Arbitru
masa getMasa() setMasa() daNota()

Dorel Lucanu

Programarea calculatoarelor (C++)

123

POO: Concursul de gimnastica (IV)

Juriu
arbitru[6] daNote() <<operator>> []() stabilesteComp()

6 Arbitru

Dorel Lucanu

Programarea calculatoarelor (C++)

124

POO: Concursul de gimnastica (V)

Clasament

1
Dorel Lucanu Programarea calculatoarelor (C++)

*
planifica() clasifica() afiseaza() stabilesteComp() nr *gim[nr]

Gimnast

125

POO: Concursul de gimnastica (VI)

Concurs

Clasament

* Gimnast

Dorel Lucanu

Programarea calculatoarelor (C++)

Arbitru

Juriu

126

POO: Concursul de gimnastica (VII)

1: daNote()

: Gimnast

: Juriu

2: daNota( )

: Arbitru

Dorel Lucanu

Programarea calculatoarelor (C++)

127

Dorel Lucanu

stabileste juriul stabileste concurenti

planifica

POO: Concursul de gimnastica (VIII)

Programarea calculatoarelor (C++)

afiseaza rezultat clasifica

evolueaza si noteaza

128

POO: Concursul de gimnastica (IX)


class Persoana { public: Persoana() {} Persoana(string , string) ~Persoana() {} void citeste(); void setNume(string nume_nou) {...} string getNume() const {...} void setTara(string tara_noua) {...} string getTara() const {...} protected: string nume, tara; }; class Gimnast : public Persoana { public: Gimnast() {} Gimnast(string un_nume, string ~Gimnast() {} float media() const ; void setNote(float[]); void setNota(float, int); void setNrord(int un_nr) {...} int getNrord() const {...} private: float nota[DIM_JURIU]; int nrord; };
Dorel Lucanu Programarea calculatoarelor (C++) 129

POO: Concursul de gimnastica (X)


class Arbitru : public Persoana { public: Arbitru() {} Arbitru(string, string) {...} void daNota(Gimnast&); int getMasa() const {...} void setMasa(int masa_noua) {...} private: int masa; }; class Juriu { public: Juriu() {} void stabilesteComp(); void daNote(Gimnast&); Arbitru& operator [] (int i) {...} private: Arbitru arb[DIM_JURIU]; };

Dorel Lucanu

Programarea calculatoarelor (C++)

130

POO: Concursul de gimnastica (XI)


class Clasament { public: Clasament() {} ~Clasament() {} void stabilesteComp(); void clasifica(); void planifica(); void afiseaza(); int getNr() const {return nr;} Gimnast& operator [] (int i) {...} private: int nr; Gimnast **gim; }; class Concurs { public: Concurs() {} ~Concurs() {} void exec(); private: Juriu juriu; Clasament clas; };
Dorel Lucanu Programarea calculatoarelor (C++) 131

Curs 13
! POO: Automatul de racoritoare (vm.cpp, vm.h, vm_demo.cpp) " definirea problemei " identificarea claselor iniiale " identificarea atributelor i funciilor " interaciunea dintre obiecte " interfa utilizator " reutilizare " interaciunea dintre Domeniul Problemei (DP) i Interfaa Utilizator (IU)

Dorel Lucanu

Programarea calculatoarelor (C++)

132

Definirea problemei
Automatele de cafea, rcoritoare sau dulciuri au nceput s-i fac simit prezena n multe locuri din Romnia. Funcionalitatea acestor automate poate fi neleas mai bine dac am avea posibilitatea s ne jucm cu diverse tipuri de automate. Pentru acest scop se dorete construcia unui sistem software care s simuleze astfel de automate.

Dorel Lucanu

Programarea calculatoarelor (C++)

133

Identificarea claselor iniiale (I)

Descrie mai nti un scenariu: Sunt o persoan (nsetat/nfometat). Merg ctre automat. Privesc ce produse sunt disponibile. Pentru fiecare produs voi vedea numele i preul. Doresc s vd ce sum am introdus n automat pn la un moment dat. Dupa ce-am introdus ceva cash, m rzgndesc, mi iau banii napoi i revin mai trziu. Sau selectez produsul pe care l doresc. mi iau produsul. mi iau restul (dac este cazul) . Plec.

Dorel Lucanu

Programarea calculatoarelor (C++)

134

Identificarea claselor iniiale (II)

SuportArt 1 DispB ani 0..n Art

Dorel Lucanu

Programarea calculatoarelor (C++)

135

Identificarea metodelor i atributelor (I)

Fiecare obiect i prezint proprietile (atributele) pe care le are i serviciile pe care le ofer: Sunt un articol i mi cunosc numele; mi cunosc preul; am abilitatea de a m vinde. Sunt un suport de articole i cunosc articolele pe care le gzduiesc. Sunt un dispozitiv de bani i mi cunosc suma colectat; pot primi bani cash; pot decide dac am colectat suficient pentru un anumit articol; tiu s dau restul; tiu s returnez banii.

Dorel Lucanu

Programarea calculatoarelor (C++)

136

Identificarea metodelor i atributelor (II)

SuportArt articole[NR_MAX_ART] vindeArtDispensabil() dispenseaza() 1 DispBani sumaColectata adaugaCash() colectaSufic() daRest() returneazaCash()

0.. n Art nume : string pret : float vinde()

Dorel Lucanu

Programarea calculatoarelor (C++)

137

Interaciunea ntre obiecte (I)

Un scenariu posibil: Sunt un suport de articole. Cineva mi spune s eliberez articolul de vndut. Verific dac articolul de vndut este dispensabil. Dac da, i spun s se vnd. Sunt un articol. Cineva mi spune s m vnd. ntreb dispozitivul de bani dac a colectat suficieni bani pentru a m vinde. Dac da, atunci i spun suportului meu s m elibereze i transmit dispozitivului de bani s dea restul.

Dorel Lucanu

Programarea calculatoarelor (C++)

138

Interaciunea ntre obiecte (II)


z : SuportArt anonim articole[0] : Art : DispBani

adaugaCash( )

vindeArtDispensabil( )

vinde( )

colectaSufic( )

dispenseaza( )

daRest( )

Dorel Lucanu

Programarea calculatoarelor (C++)

139

Programare OO: domeniul problemei

class Art { public: ... // Conexiunea cu suportul de articole Suport_Art& get_suport_art() { return *un_suport_art; } void conecteaza_la_suport(Suport_Art& suport_nou) { un_suport_art = &suport_nou; } // Conexiunea cu dispozitivul de bani Disp_Bani& get_disp_bani() { return *un_disp_bani; } void conecteaza_la_disp_bani(Disp_Bani& un_disp_nou) { un_disp_bani = &un_disp_nou; } ... }

Dorel Lucanu

Programarea calculatoarelor (C++)

140

Interfaa utilizator

C ontainerAfisareAutom at

C ontainerAfisareD ani ispB

C ontainerAfisareArt

M eniuD ispBani

D isplayBoxDispBani M eniuArt

D ispalyBoxArt

Dorel Lucanu

Programarea calculatoarelor (C++)

141

Reutilizare

Meniu

MeniuDispBani

MeniuArt

DisplayBox

DisplayBoxDispBani

DispalyBoxArt

Dorel Lucanu

Programarea calculatoarelor (C++)

142

Interaciunea dintre Domeniul Problemei (DP) si Interfaa Utilizator (IU) (I)

:M eniuD ispBani

:D ispBani

: DisplayBoxD ispBani

: SuportArt

adaugaC ) ash(

afiseazaValoare( )

v indeArtDispensabil( )

Dorel Lucanu

Programarea calculatoarelor (C++)

143

Interaciunea dintre Domeniul Problemei (DP) si Interfaa Utilizator (IU) (II)

Dorel Lucanu

Programarea calculatoarelor (C++)

144

Programare OO: interfaa utilizator

class Display_Box_Disp_Bani : public Display_Box{ public: // Constructors/destructors Display_Box_Disp_Bani() { } ~Display_Box_Disp_Bani() { } // Implementors void afiseaza_valoare(); // Accesorii Disp_Bani& get_disp_bani() { return *un_disp_bani; } void set_disp_bani(Disp_Bani& disp_nou) { un_disp_bani = &disp_nou; } private: // Date membre Disp_Bani* un_disp_bani; };

Dorel Lucanu

Programarea calculatoarelor (C++)

145

Concluzii

! Utilizarea unei notaii grafice n fazele de analiz i proiectare. ! Utilizarea unui instrument CASE pentru trasarea diagramelor. ! Crearea de scenarii care s evidenieze att proprietile obiectelor ct i relaiile dintre acestea. ! Scrierea codului numai dup ce analiza i proiectarea au produs specificaii clare i detaliate.

Dorel Lucanu

Programarea calculatoarelor (C++)

146

Curs 14
! Programare C++: Reguli i Recomandri " organizarea codului surs n fiiere " atribuirea de nume " comentarii " clase " funcii " constante " variabile " pointeri i referine " conversii de tip " structuri de control " expresii " alocarea memoriei " tratarea excepiilor " portabilitate ! Cele 10 porunci ctr programatorul C

Dorel Lucanu

Programarea calculatoarelor (C++)

147

Motivaie
! Obiectivele pecare trebuie s le ating un program sunt: " programul s fie corect, i " uor de ntreinut. ! Un program poate atinge aceste obiective dac: " are un stil consistent, " este uor de citit i de nteles, " este portabil pe alte arhitecturi, " nu are erori, i " poate fi ntreinut de diferii programatori.

Dorel Lucanu

Programarea calculatoarelor (C++)

148

Reguli i recomadri (I)


Organizarea codului surs n fiiere Structura codului " Un fiier include nu va conine mai mult dect definiia unei clase. " mparte definiiile funciilor membre sau funciile n ct mai multe fiiere. " Plaseaz codul dependent de main ntr-un fiier special. Numele fiierului Extensia: " fiiere include: .h (.hh) " fiiere cu implementri C++: .cc (.C, .cpp, .c++) " fiiere cu definiii inline: .icc Numele: " s fie unic pentru un context ct mai larg " dac este un fiier inlude ce contine definitia unei clase atunci va avea numele clasei Structura unui fiier Fiiere program (n ordinea descrierii) " Prolog: un comentariu care include ce conine fiierul, versiunea, autorul, informatii despre copyright. " Declaraii include pentru includerea fiierelor header. " Declaraii define i typedef (n ordinea: macrouri constante, macrouri funcii, typedef-uri, enum-uri) " Declararea datelor globale (externe) (n ordinea: externe, globale nestatice, globale statice) " Funciile. Gruparea funciilor depinde de obiectivul fiierului descris n prolog.

Dorel Lucanu

Programarea calculatoarelor (C++)

149

Reguli i recomadri (II)


Fiiere header "prolog "declaraii "descrierea clasei ! Fiierele header proprii nu trebuie s aib aceleai nume cu cele din biblioteci ! Includerea multipl a fiierelor include trebuie evitat: ! Urmtoarele tipuri de definiii vor fi incluse n fiiere include: "clase care snt utilizate drept clase de baz "clase care snt utilizate ca variabile membre "clase care snt utilizate ca return type sau argument type "prototipurile funciilor utilizate de ctre funciile inline membre definite n fiier. ! Definitiile claselor care snt accesate numai via pointeri * sau referine & nu vor fi incluse ca fiiere include. Utilizarea unei declaraii forward este suficient. ! Cile de acces la fiiere nu vor fi precizate. Acestea vor fi incluse ca opiuni n fiiere make.

Dorel Lucanu

Programarea calculatoarelor (C++)

150

Reguli i recomadri (III)


Atribuirea de nume " Numele variabilelor, constantelor i funciilor trebuie s nceap cu litere mici. " Numele tipurilor de dat abstracte, structuri, typedef-uri, i enum-uri vor ncepe cu liter mare. " Forma cea mai general pentru un identificator este: <prefix><nume><sufix>. Un nume este separat de sufix prin liniua de subliniere _. n general, sufixele snt generate de instrumentele C++ pentru a evita coliyiunea de nume. " Un nume care nu poate fi citit nu este bun. " Un nume nu trebuie sa fie nici prea scurt i nici prea lung. " Un nume trebuie s sugereze utilizarea sa. " Dac un nume este format din mai multe cuvinte, exceptnd primul, fiecare cuvnt va ncepe cu liter mare. Dac ultima liter a cuvntului precedent este o liter mare, atunci se va utiliza o liniu de subliniere _ separator de cuvinte. " Primul caracter nu trebuie s fie liniua de subliniere _. " Prefixele pot fi eliminate uneori prin utilizarea unei clase ca delimitator de domeniu de vizibilitate (creator de spaiu de nume).

Dorel Lucanu

Programarea calculatoarelor (C++)

151

Reguli i recomadri (IV)


Comentarii Comentariile pot fi clasificate n dou categorii: " comentarii strategice i " comentarii tactice. Clase " Seciunile publice, protejate i private vor fi declarate n aceast ordine. " Nici o funcie membr nu va fi definit n interiorul definiiei clase. " Funcii inline: funciile de acces vor fi inline funciile care numai apeleaz alte funcii vir fi inline constructorii i destructorii nu trebuie s fie inline (datorit invocrilor n cascad) " Niciodat nu specifica date membre publice sau protejate. " Accesul claselor derivate la datele membre ale clasei se face prin funcii acces protejate. " Orice funcie care nu schimb starea unui obiect va fi declarat const. " O clas care utilizeaz new pentru a aloca instane ce snt legate la variabile membre ale calsei, trebuie s defineasc un constructor copy i un operator de atribuire.
Dorel Lucanu Programarea calculatoarelor (C++) 152

Reguli i recomadri (V)


" Toate clasele care snt utilizate drept clase de baz i au funcii virtuale, vor avea un destructor virtual. Altfel, n anumite situaii va fi invocat numai constructorul clasei de baz. " Doi operatori opui (cum snt == i !=) vor fi definii amndoi sau nici unul. " O funcie membr public nu va nturna niciodat o referin non-const sau un pointer la o dat membr. " Gndete-te bine dac motenirea multipl nu poate fi nlocuit cu relaia a-part-of Funcii " Tipul ntors de o funcie trebuie specificat explicit. " Argumentele vor fi puse sau pe aceeai linie sau pe linii separate dar aliniai: " Nu utiliza argumente de funcii nespecificate (notaia eliptic). " Evit funciile cu prea muli parametri. " Utilizeaz argumente de tip pointer (Tip*) numai dac funcia memoreaz un pointer la obiectul referit de argument. Altfel, utilizeaz argumentereferin (Tip&). " Dac argumentul nu este un pointer sau de un tip predefinit, atunci utilizeaz referine constante (const T&).
Dorel Lucanu Programarea calculatoarelor (C++) 153

Reguli i recomadri (VI)


"Atunci cnd funciile snt suprancrcate, toate variaiile trebuie s aib aceeai semantic (s fie utilizate pentru acelai scop). "Parametrii (argumentele) formali trebuie s fie aceeai att n declaraie ct i n definiie. "O funcie public nu trebuie s returneze niciodat adresa unei variabile locale sau un pointer la o variabil local. "Utilizeaz funcii inline n loc de directiva #define. "Utilizeaz funcii inline numai dac e necesar. "Minimizeaz numrul de obiecte temporare create la returnarea valorii unei funcii sau la transmiterea argumentelor unei funcii. "Evit funciile lungi i complexe. Constante "Constantele vor fi definite cu const sau enum; nu utiliza niciodat #define. "Evit utilizarea valorilor numerice n cod; utlizeaz n schimb valori simbolice. Variabile "Variabilele vor fi declarate astfel nct s aib cel mai mic domeniu de vizibilitate posibil. "Fiecare variabil va fi declarat separat (ntr-o declaraie separat). "nti atribuie o valoare unei variabile i apoi utilizeaz-o. "Ori de cte ori este posibil, utilizeaz iniializarea n loc de atribuire (n special n cazul obiectelor membre).

Dorel Lucanu

Programarea calculatoarelor (C++)

154

Reguli i recomadri (VII)


Pointeri i referine " Operatorul de adres & i operatorul de defereniere * trebuie asociate direct cu numele tipurilor " Nu compara un pointer cu NULL i nici nu atribui unui pointer valoarea NULL; utilizeaz 0 n schimb. " Ori de cte ori este posibil, evit pointerii la pointeri. " Utilizeaz typedef pentru a simplifica sintaxa programului atunci cnd se declar pointeri la funcii. Conversii de tip " Nu utiliza niciodat conversii de de tip explicite (cast-uri). " Nu scrie cod acre depinde de funcii ce utilizeaz conversii de tip implicite. " Nu converti niciodat pointeri la obiecte ale unei clase derivate la pointeri la obiecte ale clase de baz virtuale. " Niciodat nu converti un const la un non-const. Structuri de control al calculului " Acoladele care delimiteaz un bloc vor fi puse pe aceeai coloan i pe linii separate. " Structurile de control if, else, while, do, i for vor fi urmate de un bloc chiar dac acesta este vid. Dorel Lucanu Programarea 155
calculatoarelor (C++)

Reguli i recomadri (VIII)


" Codul corespunztor unei etichete case va fi urmat totdeauna de un break. " instruciune switch va conine totdeauna o clauz default. " Nu utiliza niciodat goto. " Alegerea instruciunii repetitive (for, while, dowhile) va depinde de utilizarea sa specific. " Utilizeaz totdeauna variabile unsigned pentru variabile ce nu vor lua valori negative. " Utilizeaz ntotdeauna limite inferioare inclusive (<=) i limite superioare (>). " Evit utilizarea instruciunii continue. " Utilizeaz break pentru a iei din bucle repetitive dac aceasta evit utilizarea de "flag"-uri. " Nu scrie if(test) sau if(!test) dac test este un pointer. Expresii " Utilizeaz parantezele pentru a clarifica ordinea de evaluarea operatorilor n expresii.

Dorel Lucanu

Programarea calculatoarelor (C++)

156

Reguli i recomadri (IX)


Alocarea memoriei " Nu utiliza malloc, realloc, sau free. " Utilizeaz ntotdeauna parantezele drepte ([]) pentru delete atunci cnd se dealoc tablouri. " Evit datele globale dac este posibil. " Nu te atepta ca altcineva se dealoce spaiul de memorie alocat de tine. " Atribuie o valoare nou unui pointer care "pointeaz" la un spaiu dealocat. Tratarea excepiilor " Fii sigur c toate excepiile snt controlate n program astfel nct ori de cte ori apare una controlul va fi dat mecanismului de tratare a excepiilor. " Scrie cod care trateaz codurile de eroare ntoarse de funciile din biblioteci.

Dorel Lucanu

Programarea calculatoarelor (C++)

157

Reguli i recomadri (X)


Portabilitate " Evit utilizarea direct a tipurilor predefinite n declaraii " Nu presupune ca int i long au aceeai lungime. " Nu presupune c un int este reprezentat pe 32 bii. " Nu presupune c char este signed sau unsigned. " Nu presupune c pointeri i ntregii au aceeai lungime. " Utilizeaz conversii de tip explicite pentru aritmetica ce utilizeaz valori signed i unsigned. " Nu presupune c tii cum este reprezentat n memorie o instan a unui tip de dat. " Nu presupune c instanele long, float sau long double pot ncepe la adrese arbitrare. " Programul nu trebuie s depind de modul particular n care depirile superioare i cele inferioare snt rezolvate. " Nu presupune c operatorii ntr-o expresie snt executai ntr-o ordine definit. " Nu presupune c tii cum este implemntat mecanismul de apelare a funciilor. " Nu presupune c obiectele snt iniializate prin apelarea constructorilor ntr-o ordine special. " Nu scrie cod care depinde durata de via a obiectelor temporare" Evit operaiile de iftare n locul celor aritmetice. " Evit aritmetica pointerilor.
Dorel Lucanu Programarea calculatoarelor (C++) 158

También podría gustarte