Documente Academic
Documente Profesional
Documente Cultură
C
++{};
C++ Acest curs
› Introducere smart pointers
› Exemplu de implementare a unui smart pointer
› unique_ptr, shared_ptr, weak_ptr
› Subiect examen 2017 - 2018
C++ Introducere
› Programele C++ gestioneaza memoria dinamica cu new si delete
in acelasi stil mostenit din limbajul C
› Programele moderne (Python, Java & C#) gestioneaza memoria
prin intermediul unei tehnici numite garbage collection
› In astfel de limbaje doar se apeleaza new sau un echivalent,
eliberarea memoriei fiind realizata de garbage collection atunci
cand programul nu mai foloseste obiectele allocate dinamic
› Garbage collection adauga un overhead – consum de memorie
mai mare, cod suplimentar, afecteaza eficienta la run tine.
› Din acest motiv C++ nu ofera garbage collection
C++
› Limbajele GB in mod tipic aloca toate obiectele in heap
gestionand astfel memoria intr-o maniera uniforma
› C++ suporta statically-allocated si stack-allocated
objects, precum si heap-allocated objects.
› Heap allocation este putin mai lenta iar fragmentarea
memoriei heap poate degrada performantele programului.
› C++ urmeaza sloganul “You only pay for what you use”
insemnand ca programele care nu au nevoie de heap nu sunt
“penalizate” (costul aferent utilizarii nu apare la run time).
C++
› Totusi C++ furnizeaza atat beneficiile unui program non GB
cat si cele ale unui program GB atunci cand este necesar.
Metodele puse la dispozitie pentru gestiunea automata a
memorie dinamice sunt:
– apelul delete in destructor
– utilizarea unor functii globale make(…) respectiv destroy(…) sau a
unor obiecte allocator cu metodele (allocate, deallocate
etc.) care implementeaza alocarea si dealocarea memoriei (este
eliminat astfel apelul direct al operatorilor new si delete)
– utilizarea smart pointers
C++ Smart pointers
› Pointeri care “stiu” exact cand sa dealoce memoria referita.
› Sunt definiti printr-o clasa “ambalaj” peste un pointer normal
(precum clasa iterator) ce are operatori ca * si ->
supraincarcati
› Obiectele unor astfel de clase “arata” ca pointeri normali dar
pot face multe lucruri: eliberarea automata a memoriei,
contorizare referinte etc.
C++ Utilizare clasica a unui pointer
int main(void)
{
char* pName = new char[1024];
…
SetName(pName);
…
…
if (null != pName)
{
delete[] pName;
}
}
class Person
{
int age;
void Display()
{
cout << "Name = " << pName << " Age " << age << endl;
}
void Shout()
{
cout << "Ooooooooooooooooo";
}
};
void main()
{
Person* pPerson = new Person("Gica Popescu", 22);
pPerson->Display();
delete pPerson;
}
#include<iostream>
using namespace std;
Smart pointer
C
++ class SmartPtr
{
int *ptr; // Actual pointer
public:
// constructor de initializare/conversie
// de remarcat utilizarea cuvantului cheie explicit
explicit SmartPtr(int *p = NULL) { ptr = p; }
// Destructor
~SmartPtr() { delete(ptr); }
//supraincarcarea operatorului *
int &operator *() { return *ptr; }
};
int main()
{
SmartPtr ptr(new int());
*ptr = 20;
cout << *ptr;
return 0;
}
template <class T>
class SmartPtr
{
C++ T *ptr; // Actual pointer
public:
// Constructor
explicit SmartPtr(T *p = NULL) { ptr = p; }
// Destructor
~SmartPtr() { delete(ptr); }
int main()
{
SmartPtr<Person> ptr(new Person(“Gica Popescu " , 22));
ptr->Display();
return 0;
}
C++ Contorizarea referintelor
class RefCounter
{
int count; // contor de referinte
public:
RefCounter (){ count = 0; }
// Incrementare contor de referinte
void AddRef() { count++; }
template<class T>
SmartPtr<T>::SmartPtr(T* p): ptr(p), reference(0)
{
// creaza un obiect RefCounter
reference = new RefCounter();
// incrementeaza counterul de referinte
reference->AddRef();
}
template<class T>
SmartPtr<T>::SmartPtr(const SmartPtr<T>& sp): ptr(sp.ptr), reference(sp.reference)
{
// Copiaza adresa continuta de ptr si adresa continuta de pointerul reference
// incrementeaza counterul de referinte
reference->AddRef();
}
C++
template<class T>
SmartPtr<T>::~SmartPtr()
{
// decrementeaza counterul de referinte
// daca referinta este zero dealoca data si obiectul referinta
if (reference->Release() == 0)
{
delete ptr;
delete reference;
}
}
template<class T>
SmartPtr<T>::SmartPtr<T>& operator = (const SmartPtr<T>& sp)
C++ {
if (this != &sp) // evita auto asignarea
{
// decrementeaza counterul de refinte curent
// daca refeinta devine zero sterge data si referinta
if (reference->Release() == 0)
{
delete ptr;
delete reference;
}
SmartPtr<Person> r;
r = p;
r->Display();
// r, apel destructor
}
p->Display();
// p, apel destructor
//apel delete Person
}
C++ Aplicatii: memory leaks
› Fie urmatoarea secventa de cod:
void MakeNoise()
{
Person* p = new Person("Gica Popescu", 22);
p->Shout();
delete p;
}
void MakeNoise()
{
SmartPtr<Person> p(new Person(“Gica Popescu", 22));
p->Shout();
}
C++ Clase smart pointers in STD
› std::unique_ptr
– nu are counter de referinte
– nu are constructor de copiere
– nu are operator de asignare (de copiere)
– are constructor de mutare
– are operator de asignare de mutare
http://www.cplusplus.com/reference/memory/unique_ptr/
› std::shared_ptr
– exemplul prezentat in curs
http://www.cplusplus.com/reference/memory/shared_ptr/
› std::weak_ptr
– nu incrementeaza contorul de referinte al unui shared_ptr
– expired()
– lock()
http://www.cplusplus.com/reference/memory/weak_ptr/
C++