Documente Academic
Documente Profesional
Documente Cultură
Gestiunea memoriei in C
Incapsulare, abstractizare in C
Limbajul de programare C++
Elemente de limbaj noi (c++ 11/14)
Lecture 4
Clase si obiecte
Gestiunea memoriei in C++ (RAII)
Template
Definiii de metode
Metodele declarate n clas sunt definite ntr-un fisier separat (.cpp)
Se foloseste operatorul :: (scope operator) pentru a indica apartanena metodei la clas
Similar ca i la module se separa declaraiile (interfaa) de implementri
/**
* Add an integer number to the rational number
*/
void Rational::add(int val) {
a = a + val * b;
}
Putem folosi metode inline doar pentru metode simple (fr cicluri)
Compilatorul insereaz (inline) corpul metodei n fiecare loc unde se apeleaz metoda.
Obiect
Clasa descrie un nou tip de data.
Obiect - o instana noua (o valoare) de tipul descris de clas
Declaraie de obiecte
<nume_clas> <identificator>;
'
Rational r1 = Rational{1, 2};
Rational r2{1, 3};
Rational r3;
cout << r1.toFloat() << endl;
cout << r2.toFloat() << endl;
cout << r3.toFloat() << endl;
Rational r4 = Rational(1, 2);
Putem accesa atributul folosind pointerul this. Util daca mai avem variabile cu acelai nume n
metod (parametru, variabil local)
this: pointer la instana curent. Avem acces la acest pointer n toate metodele clasei, toate
metodele membre din clas au acces la this.
Constructor
Rational::Rational() {
a = 0;
this->b = 1;
}
Este apelat de fiecare dat cnd un obiect nou se creaz nu se poate crea un obiect fr a
apela (implicit sau explicit) constructorul
Orice clas are cel puin un constructor (dac nu se declar unu exist un constructor implicit)
Constructorul fr parametri este constructorul implicit (este folosit automat la declararea unei
variabile, la declararea unei vector de obiecte)
Intr-o clas putem avea mai muli constructori, constructorul poate avea parametrii.
class Rational {
public:
Rational();
Rational(int a,int b);
private:
int a;
int b;
};
Rational::Rational() {
a = 0;
this->b = 1;
}
Rational::Rational(int a,int b):a{a},b{b} {
}
Atributele clasei se pot initializa (member initialization list) adaugand o lista inainte de corpul
metodei (expresia intre : si { inceputul corpului constructorului
Varianta cu lista de initializare are cateva beneficii:
poate fi mai eficient (initializeaza direct atributul - loc de default constructor apoi copiere)
poate fi singura modalitate de initializare (ex atribut referinta sau const)
Constructor de copiere
Constructor folosit cnd se face o copie a obiectului
la declarara de variabila cu initializare
la transmitere de parametrii (prin valoare)
cnd se returneaz o valoare dintr-o metod
Rational r3{ r2 };
Rational r4 = r3;
Exist un constructor de copiere implicit (chiar dac nu se declar n clas) acesta copieaz
fiecare cmp al obiectului (nu este tot timpul potrivit - mai ales n cazul n care avem attribute
alocate dinamic)
Putem cere explicit varianta default pentru constructor de copiere
Rational(const Rational& ot) = default;
Putem crea clase astfel incat copierea obiectelor sa fie interzisa (eroare de comilare)
Rational(const Rational& ot) = delete;
= default se poate folosi si pentru oricare dintre functiile speciale dintr-o clasa
Orice variabila creata cu new trebuie distrusa cu delete. (fiecare new exact
un delete). Programatorul este responsabil cu eliberarea memoriei
Pentru a distruge vectori statici se foloseste delete []
char* nume = new char[20];
delete[] nume;
//se apeleaza constructorul fara parametrii de 10 ori
Pet* pets = new Pet[10];
delete[] pets;
Destructor
DynamicArray::~DynamicArray() {
delete[] elems;
}
Folosirea const permite definirea mai precis a contractului dintre apelant i metod
Ofer avantajul c restriciile impuse se verific la compilare (eroare de compilare dac
ncercam s modificm valoarea/adressa)
Putem folosi const pentru a indica faptul ca metoda nu modific obiectul (se verific la
compilare)
/**
* Get the nominator
*/
int getUp() const;
/**
* get the denominator
*/
int getDown() const;
/**
* Get the nominator
*/
int Rational::getUp() const {
return a;
}
/**
* get the denominator
*/
int Rational::getDown() const {
return b;
}
const permite descrierea mai precisa a contractului (interfata) intre metoda si cel care apeleaza
/**
* Get the nominator
*/
int Rational::getUp() const {
return a;
}
/**
* get the denominator
*/
int Rational::getDown() const {
return b;
}
Daca intr-o functie avem un parametru formal const&, functia nu poate modifica starea
obiectului => poate apela doar metode const al obiectului
Supraincarcarea operatorilor
C++ permite definirea semantici pentru operatori asupra tipurilor definite de utilizator.
ex. ce se intampla daca scriu a+b unde a, b sunt obiecte de un tip definit de utilizator
/**
* Compute the sum of 2 rational numbers
* a,b rational numbers
* rez - a rational number, on exit will contain the sum of a and b
*/
void add(const Rational &nr);
/**
* Overloading the + to add 2 rational numbers
*/
Rational operator +(const Rational& r) const;
/**
* Sum of 2 rational number
*/
void Rational::add(const Rational& nr1) {
a = a * nr1.b + b * nr1.a;
b = b * nr1.b;
int d = gcd(a, b);
a = a / d;
b = b / d;
}
/**
* Overloading the + to add 2 rational numbers
*/
Rational Rational::operator +(const Rational& r) const {
Rational rez = Rational(this->a, this->b);
rez.add(r);
return rez;
}
Rule of tree
void testCopy() {
DynamicArray ar1;
ar1.addE(3);
DynamicArray ar2 = ar1;
ar2.addE(3);
ar2.set(0, -1);
printElems(&ar2);
printElems(&ar1);
}
Assignment operator
DynamicArray& DynamicArray::operator=(const DynamicArray& ot) {
if (this == &ot) {
return *this;// protect against self-assignment (a = a)
}
delete[] this->elems;
//delete the allocated memory
this->elems = new TElem[ot.capacity];
for (int i = 0; i < ot.size; i++) {
this->elems[i] = ot.elems[i];
}
this->capacity = ot.capacity;
this->size = ot.size;
return *this;
}
Destructor
DynamicArray::~DynamicArray() {
delete[] elems;
}
//vers 1
typedef struct {
char name[20];
int age;
} Pet;
//a simple copy (bitwise) will do
//vers 2
typedef struct {
char* name;
int age;
} Pet;
// when we make a copy we need to
take care of the name field
Template
Function template:
T este parametru template (template parameter), este un tip de date , argument pentru
functia sum
Instantierea templatului crearea codului efectiv inlocuind T cu tipul int:
int sum = sumTemp<int>(1, 2);
Class template:
template<typename ElementType>
class DynamicArray {
public:
/**
* Add an element to the dynamic array to the end of the array
* e - is a generic element
*/
void addE( ElementType r);
/**
* Delete the element from the given position
* poz - the position of the elem to be deleted, poz>=0;poz<size
* returns the deleted element
*/
ElementType& deleteElem(int poz);
/**
* Access the element from a given position
* poz - the position (poz>=0;poz<size)
*/
ElementType& get(int poz);
/**
* Give the size of the array
* return the number of elements in the array
*/
int getSize();
/**
* Clear the array
* Post: the array will contain 0 elements
*/
void clear();
private:
ElementType *elems;
int capacity;
int size;
};
separat interfata (ce vede cel care foloseste) de implementare (cum e implementat)
specificatii abstracte (fara referire la detalii de implementare)
ascundere detalii de implementare (data protection)
Clase
implementare cu void*
nu pot adauga constante (1, 3.5) pot adauga doar adrese
in multe locuri trebuie sa folosesc cast
pot adauga in acelasi lista adrese la elemente de tipuri diferite
implementare cu template
lista poate contine atat adrese cat si obiectele, pot adauga valori simple
Rational::nrInstances
Clase/functii friend.
friend permite accesul unei functii sau clase la campuri/metode private dintr-o clasa
Clasa friend
class ItLista {
public:
friend class Lista;
.
template<typename E>
class Set {
friend class Set_iterator<E> ;
Functie friend
class List {
public:
friend void friendMethodName(int param);
Util si pentru:
class AClass {
public:
AClass operator+(int nr); //pentru: AClass a; a+7
private:
int a;
friend AClass operator+(int nr, const AClass& ob);//pentru: AClass a;
};
7+a