Documente Academic
Documente Profesional
Documente Cultură
PROGRAMARE
ORIENTATĂ OBIECT
ÎN C++
Obiectiv
• Să te învețe cum să gândești și să programezi folosind paradigma Orientat
Obiect (OO) ...... și să codezi în C ++ (editare cod sursă, compilare, depanare în
debugger și execuție)
Evaluare în 2019
• 50% activități pe parcursul semestrului (în mare la seminar)
• 20% - test practic (fără erori de compilare) – săptămâna 7 sau 8
• 15% - test grilă (concepte și secvențe de cod) – săptămâna 12th
• 15% - teme/teste/grile la seminar sau la curs – fii activ pe perioada semestrului
• 50% examen final – examen practic care presupune scrierea unei aplicații fără
erori de compilare C ++ ... ... care chiar funcționează
• Recapitulare
• Clase (Definire, Atribute, Constructori, Destructor, Metode, Interfață)
• Supraîncărcare operatori
• Lucru cu stream-uri (consola, fișiere)
• Derivare clase (Moștenire, Ierarhii de clase, Polimorfism, Funcții
virtuale, Vectori de pointeri de obiecte)
• Clase Template
• STL – Standard Template Library
• www.acs.ase.ro/cpp
• Ion Smeureanu, Marian Dardala – “Programarea orientata obiect in limbajul
C++”, Editura CISON, 2002
• Ion Smeureanu – “Programarea in limbajul C/C++”, Editura CISON, 2001
• Standardul: Bjarne Strastroup – The Creator of C++, “The C++ Programming
Language”-3rd Edition, Addison-Wesley,
http://www.research.att.com/~bs/3rd.html
• https://en.cppreference.com/w/
• Orice tutorial găsit pe Internet
• Super rapid
• Oferă o implementare specifică pentru o mulțime de tpuri de
hardware (ai nevoie doar de compilator specific)
• Nu este nevoie de o mașină virtuală sau de un interpreter
• Timp de mulți ani în top 5 limbaje de programare utilizate în
indexul TIOBE(3rd în Octombrie 2017 și 4th acum în Octombrie
2018 ) - https://www.tiobe.com/tiobe-index/
catalin.boja@ie.ase.ro 9
CE CONȚINE ACEST CURS
Java C++
http://blog.carlesmateo.com/2014/10/13/performance-of-several-languages/
catalin.boja@ie.ase.ro 11
DE CE C++
https://helloacm.com/a-quick-performance-comparison-on-languages-at-codeforces/
• Trebuie să
• Acceptați că există întotdeauna loc pentru îmbunătățiri (nimeni nu este perfect)
• Fiți persistenți în atingerea obiectivelor
• Vă folosiți imaginația pentru a rezolva problemele
Source http://www.vikingcodeschool.com/posts/why-learning-to-code-is-so-damn-hard
catalin.boja@ie.ase.ro 16
CAUZE PENTRU A NU REUȘI
Erori de compilare
• Generate de greșeli în editarea
codului
• >99% deoarece nu este cunoscută
sintaxa
• Indicate clar de compilator în
fereastra Errors (VS)…..si Warnings
• NU au legătură cu complexitatea
programului, algoritmul folosit, etc
1. După fiecare curs și seminar verifică dacă ai înțeles conceptele (altfel citește și întreabă
colegii și profesorii)
2. Scrie cât mai multe programe C++ (dacă toate îți merg din prima……….ceva nu este în
regulă)…dar nu le copia din exemplele de la curs sau seminar (definește-ți propriile
exemple)
3. Dacă toate încercările inițiale au erori de compilare și/sau de execuție …………..ești
pe drumul cel bun
4. Dacă ești la pasul 2, nu renunța………..corectează-le citind suportul de curs și căutând
resurse pe Internet (nu tot ce găsești pe stackoverflow este și corect)
5. Dacă NU reușești în 2-3 ore să corectezi o problemă cere ajutor (colegii și profesori)
6. NU renunța să scrii cât mai multe programe……..cam 2-3 ore pe săptămână
PAW – .NET C#
POO - C++
DAM – Java
Android
TW –
React/Angular
Anul 3
AD - Python
CTS - Java
https://www.visualstudio.com/downloads/ https://eclipse.org/cdt/
Varianta free Community Edition este ok
void main()
{
char a = 7, b = 9;
short int c;
c = a+b;
MicroProcesor RAM
}
BUS
1Byte HDD
Exemple:
• int* pi ; // pointer la int
• char** ppc ; // pointer la pointer de char
• int * ap[1 0 ]; // sir de 10 pointeri la int
Valoarea 0 pentru un pointer este o valoare nula. Aceasta este asociata cu simbolul
#define NULL 0
sau cu constanta
const int NULL = 0;
Aritmetica pointerilor:
• pentru un pointer de tip T*, operatorii --/++ asigura
deplasarea inapoi/inainte cu sizeof(T) octeti;
• pentru un pointer de tip T* pt, expresia pt + k sau pt – k
este echivalenta cu deplasarea peste k * sizeof(T) octeti;
• diferenta dintre 2 pointeri din interiorul aceluiasi sir de
valori reprezinta numarul de elemente dintre cele doua
adrese;
• adunarea dintre 2 pointeri nu este acceptata;
2008 – 2018 © Catalin Boja 29
POINTERI – CONSTANȚI
• definire:
tip_return (* nume_pointer) (lista parametrii);
• inițializare:
nume_pointer = nume_functie;
void main()
BEGIN
int vb = 10;
int vector[NMAX];
if(vb < NMAX) then printf(“mai
mic”);
else printf(“mai mare”);
END
Tipul enumerativ:
enum denumire {lista simboluri} lista variabile
Exemplu:
Compilare condiționată:
#if expresie_1
secventa_1
#elif expresie_2
secventa_2
…
#else
secventa_n
#endif
2008 – 2018 © Catalin Boja 41
PREPROCESARE
Operatorii # si ##:
• sunt utilizați împreună cu #define
• operatorul # (de înșiruire) transforma argumentul într-
un sir cu “”;
#define macro1(s) # s
• operatorul ## (de inserare) concatenează 2 elemente
#define macro2(s1, s2) s1 ## s2
2008 – 2018 © Catalin Boja 42
ELEMENTE NOI - C++
• lucru cu consola
• citire de la consola: cin >> nume_variabila
• afișare la consola: cout << nume_variabila
• alocare spațiu dinamic (HEAP)
• alocare spațiu: nume_pointer = new tip_data[nr_elemente]
• dealocare spațiu: delete [] nume_pointer
• referința &
• definire parametrii ieșire pentru funcții: void Interschimbare( int &a,
int &b)
Sintaxa definire:
class Nume_Clasa
{
tip_acces:
atribute;
functii membre;
tip_acces:
atribute;
functii membre;
};
• private
• implicit pus de compilator la începutul clasei;
• permite accesul doar din interiorul clasei;
• protected
• are utilizare in cadrul ierarhiilor de clase obținute prin derivare;
• permite accesul din interiorul clasei si din interiorul; claselor
derivate;
• public
• permite accesul din interiorul clasei si din afara ei;
class Test
{
public:
const int atribut_1;
const char atribut_2;
}
2008 – 2018 © Catalin Boja 50
CLASE – ATRIBUTE CONSTANTE
class Test
{
public:
static int vb_1;
static char vb_2;
};
2008 – 2018 © Catalin Boja 53
CLASE – ATRIBUTE STATICE
class Test
{
public:
static int vb_1;
};
int Test:: vb_1;
• sintaxa:
class Nume_clasa {
public:
Nume_clasa( ){…}
};
• apel:
void main () {
Nume_clasa obiect_1;
Nume_clasa obiect_2(parametrii constructor)
}
class Test {
private:
int atribut_1;
public:
…
};
• constructor implicit:
Test ( ) { atribut_1 = 0; }
• constructor cu parametri
Test ( int val ) { atribut_1 = val ; }
Test ( int val ): atribut_1(val ) {}
• sintaxa:
class Nume_clasa {
public:
~Nume_clasa( ){…}
};
• apel implicit:
void main () {
Nume_clasa obiect_1;
}
class Nume_clasa {
public:
static void Metoda_1( ){…}
};
void main( ) {
Nume_clasa::Metoda_1( );
}
2008 – 2018 © Catalin Boja 69
CLASE – METODE INLINE
class Nume_clasa {
private:
int Atribut_1;
public:
int Get_Atribut_1( ) { return Atribut_1;}
void Set_Atribut_1(int val) {
//validare val
Atribut_1 = val;
}
};
class Nume_clasa {
…
};
Nume_clasa Metoda1 (Nume_clasa
obiect);
constructor de copiere:
• sintaxa:
class Nume_clasa {
public:
Nume_clasa(Nume_clasa & ob_existent){…}
};
• apel explicit:
void main () {
Nume_clasa obiect_1(…);
Nume_clasa obiect_2 = obiect_1;
}
class Test {
public:
apel implicit
Test (Test & ob_existent){…} constructor de
void Metoda1(Test ob1, Test *ob2) {…} copiere
Test Metoda2(Test ob1) {…}
};
void main () {
Test obiect_1, obiect_2, obiect_3, obiect_4;
obiect_1.Metoda1(obiect_2, obiect_3);
obiect_4 = obiect_1.Metoda2(obiect_2);
}
• apel explicit :
class Nume_clasa {
…
};
void main () {
Nume_clasa obiect_1(…);
Nume_clasa obiect_2(…);
obiect_2 = obiect_1;
}
void main () {
Nume_clasa obiect_1(…);
Nume_clasa obiect_2(…);
obiect_2 = obiect_1;
}
• inițializare:
nume_pointer_metoda = & Nume_clasa:: nume_functie_membra ;
• utilizare:
Nume_clasa obiect, *pobiect = &obiect;
tip_returnat variabila = (obiect.* nume_pointer_metoda)(parametrii)
tip_returnat variabila = (pobiect->*nume_pointer_metoda)(parametrii)
void main()
{
//identificare forma exacta
int rez1 = suma(5,4);
//identificare forma functie prin conversii nedegradante
int rez2 = suma('0',5);
//identificare forma functie prin conversii degradante
int rez3 = suma(4.6, 5);
}
• NU garantează comutativitatea;
• formele post si pre sunt supraîncărcate diferit;
2008 – 2018 © Catalin Boja 92
SUPRAÎNCĂRCARE OPERATORI
class Test{
Test operator+(Test t, int vb){
…
}
};
operator + cu 3 parametri !!!!!
2008 – 2018 © Catalin Boja 94
SUPRAÎNCĂRCARE OPERATORI
class Test{
int info;
friend ostream& operator << (ostream &, Test);
friend istream& operator >> (istream &, Test &);
};
class Test{
…
friend int operator+= (Test,int);
};
class Test{
int valoare;
…
int operator int () { return valoare;}
};
void main(){
Test t;
int vb = t; //echivalent cu vb = t.valoare;
}
• are un parametru;
• prin funcție membra sau independentă;
class Test{
int valoare;
…
void operator ! () {valoare*=-1;}
};
void main(){
Test t;
!t;
}
class Test{
int valoare;
…
Test& operator ,(Test& t) {return t;}
};
void main(){
Test t1,t2, t3,t4;
t4 = (t1,t2,t3); //echivalent cu t4 = t3;
}
• REUTILIZARE COD;
• dezvoltarea de noi entități (clase) pornind de la cele
existente
• Derivare – clasa existenta se derivează într-o nouă clasă;
• Moștenire – clasa nou definită moștenește atributele +
metodele clasei derivate (clasei de baza);
class Baza{
};
class Derivat : tip derivare Baza{
};
public public
private private
constructor Baza
constructor Derivat
2008 – 2018 © Catalin Boja 123
C++ – DERIVARE / MOȘTENIRE
• construcție obiect derivat = CONSTRUCTOR BAZA +
CONSTRUCTOR DERIVAT
class Baza{ apel implicit Baza()
Baza(){…}
Baza(lista parametri){…}
}; apel explicit
:Baza(lista parametri)
class Derivat : tip derivare Baza{
Derivat(){…};
SAU
Derivat() : Baza(lista parametri) {…}
};
2008 – 2018 © Catalin Boja 124
C++ – DERIVARE / MOȘTENIRE
• distrugere obiect derivat = DESTRUCTOR DERIVAT +
DESTRUCTOR BAZA
ATENTIE ! Fiecare destructor trebuie să se concentreze strict pe
ceea ce a făcut constructorul clasei.
class Baza{
int atribut1;int atribut2;
Baza& operator=(Baza& b){…}
Baza(Baza& b) {…}
};
class Derivat : private Baza{
int atribut_nou;
};
d1 d2
Derivat d3 = d1;
copiere bit cu bit
}
constructor Derivat
d3 d1
• UPCASTING
void main(){
Derivat d1,
*pd1;
b1 d1
Baza b1, *pb1;
b1 = d1;
b1 d1
pd1 = &d1;
pb1 = pd1;
}
2008 – 2018 © Catalin Boja 129
C++ – DERIVARE / MOȘTENIRE
pd1 = &d1;
pb1 = pd1; b1 d1
funcții VIRTUALE:
• natura virtuala a unei funcții se moștenește
• funcția de pe ultimul nivel unde a fost redefinita
răspunde pentru subierarhia ei;
• funcția devine si rămâne virtuala de la prima definire
a ei din ierarhie a care este anunțată ca fiind virtuală
• ATENTIE la destructori virtuali
2008 – 2018 © Catalin Boja 137
CLASE – POLIMORFISM
se implementează când
class Vehicol{ intre clasa derivata si
…
};
clasa de baza exista
relația is a;
class Automobil: public Vehicol{
…
};
class Motor{
… se implementează
}; când intre clasa
principala si cea
class Automobil{ inclusa exista o
Motor motor; relație has a;
};
class Baza_abstracta{
virtual int Metoda1(int a) = 0
};
Dreptunghi Cerc
Patrat
char * DenumireModel
2008 – 2018 © Catalin Boja 148
CLASE ABSTRACTE
Exemplu utilizare ierarhie:
&Dreptunghi::Arie
Model2D * ListaModele[3];
&Dreptunghi::Perimetru
ListaModele[0] = new Dreptunghi(); &Dreptunghi::GetNrPuncte
& Patrat::Arie
try {
if(conditie_1) throw exceptie;
if(conditie_2) throw exceptie_generala;
}
catch(exceptie){ //secventa prelucrari}
blocul try{…}
• conține secvența de prelucrări care generează excepții prin throw;
• are asociat minim un bloc catch
• intre blocul try si blocurile catch asociate nu exista alte instrucțiuni
blocul catch( tip_exceptie exceptie)
• gestionează o excepție de tipul anunțat
blocul catch( …)
• gestionează toate tipurile de excepții
2008 – 2018 © Catalin Boja 156
C++ – GESTIUNE EXCEPȚII
void functie_terminate(){
cout << "functie_terminate()";
exit(-1);
}
set_terminate( functie_terminate );
DEZAVANTAJE:
• poate complica codul;
• in C++ reprezintă o alternativa la tratarea erorilor local (in
interiorul funcției)
• sunt ineficiente din punctul de vedere al execuției programului
• captarea excepțiilor prin valoare;
• nu pentru evenimente asincrone (in C++ excepția si handler-ul
ei sunt prezente in același apel (call stack)
• IMPORTANT generarea excepțiilor in funcțiile destructor si
constructor;
2008 – 2018 © Catalin Boja 162
C++ – GESTIUNE EXCEPȚII
DEZAVANTAJE:
• generarea de excepții in constructor întrerupe execuția
acestuia si obiectul nu mai este construit (NU se mai
apelează destructorul) însă memoria alocata dinamic
pana la throw generează memory leak
• generarea de excepții in destructor întrerupe execuția
acestuia si pot fi generate memory leaks
2008 – 2018 © Catalin Boja 163
C++ – GESTIUNE EXCEPȚII
exception
logic_error runtime_error
domain_error domain_error
invalid_argument invalid_argument
out_of_range out_of_range
http://www.tutorialspoint.com/cplusplus/cpp_exceptions_handling.htm
CLASE – STREAM-URI
ios streambuf
istream ostream
iostream
• dec • setbase(int)
• hex • setfill()
• oct • setw(int)
• setprecision(int) • setiosflags(long)
• endl • resetiosflags(long)
• ends
• ws
• flush
• ios::left • ios::fixed
• ios::right • ios::showpoint
• ios::internal • ios::skipws
• ios::dec • ios::stdio
• ios::hex • ios::uppercase
• ios::showpos • ios::unitbuf
• ios::showbase
• ios::scientific
Mod deschidere:
• ios::in - deschis in citire
• ios::out - deschis in scriere
• ios::ate - deschidere si poziționare la sfârșit
• ios::app - deschidere pentru adăugare
• ios::trunc - deschidere si ștergere conținut
• ios::nocreate - nu deschide daca nu exista
• ios::noreplace - nu deschide daca el exista
• ios::binary -deschidere in mod binar
2008 – 2018 © Catalin Boja 177
C++ – LUCRU CU FIȘIERE
bool eof()
Poziționare in fișiere:
• pentru fișiere de input (citire):
istream & istream::seekg(long streamoff, ios::seekdir)
sau
istream & istream::seekg(long streampos)
unde:
ios::seekdir poate fi:
ios::beg – începutul fișierului
ios::cur – poziția curentă în fișier
ios::end – sfârșitul fișierului
2008 – 2018 © Catalin Boja 181
C++ – LUCRU CU FIȘIERE
Poziționare in fișiere:
• pentru fișiere de output(scriere):
ostream & ostream::seekp(long streamoff, ios::seekdir)
sau
ostream & ostream::seekp(long streampos)
unde:
ios::seekdir poate fi:
ios::beg – începutul fișierului
ios::cur – poziția curentă în fișier
ios::end – sfârșitul fișierului
Poziționare in fișiere:
• pentru fișiere de output(scriere) determinarea poziției
curente se face prin metoda long tellp() ce returnează
numărul de octeți de la începutul fișierului
• pentru fișiere de input(citire) determinarea poziției
curente se face prin metoda long tellg() ce returnează
numărul de octeți de la începutul fișierului
2008 – 2018 © Catalin Boja 183
C++ – LUCRU CU FIȘIERE
Tipuri de fișiere:
• Organizare secvențiala cu înregistrări de lungime fixă
și variabilă
• Acces direct
• Fișiere indexate
• Fișiere de tip invers
class T
typename T
• definire:
template <typename T1, typenameT2, …>
• definire:
template <typename T>
T aduna (T a, T b){ return a+b;}
Clase template:
template <class T1, typename T2, …, tip1 c1, tip2 c2, …>
class nume_clasa{
tip concret
…
}
Vector<int> v1;
Vector<int,10> v1;
Derivare:
template<typename T> class bt {…};
class b {…};
• clasa template derivata din clasa template
template<typename T> class d: public bt<T> {…}
• clasa template derivata din clasa non template
template<typename T> class d: public b {…}
• clasa non template derivata din clasa template
template class d: public bt<int> {…}
CONTAINERE
ITERATORI ALGORITMI
0 1 2 3 4
“Piata Victoriei” “Calea Dorobanti” “Piata Victoriei” “Piata Romana” “Calea Dorobanti”
• secvențiale:
• vector;
• list;
• deque;
• asociative (valoare – cheie):
• set (mulțime de chei unice, sortate)
• multiset (mulțime de chei, sortate)
• map (mulțime valori-chei unice, sortate)
• multimap (mulțime valori-chei sortate)
• adaptive:
• stack
• queue
• priority_queue
typeid():
• determina tip conținut pointer printr-o structura de tip type_info
(typeinfo)
ComponenteGrafice::Model2D *pModel;
pModel = new ComponenteGrafice::Dreptunghi();
cout << typeid(*pModel).name() << endl;
dynamic_cast<T>()
• este “type-safe down-cast”;
• este o funcție template;
• permite conversia la tipul T pentru un pointer la
obiect de baza dacă conținutul de la adresa data
de pointer este de tip T
• evita erorile de conversie imposibile;
• returnează T* daca este posibil, altfel NULL;
2008 – 2018 © Catalin Boja 207
RTTI
if(dynamic_cast<Dreptunghi*>(pModel))
oDreptunghi.Arie();