Sunteți pe pagina 1din 50

C1- OOP – clasa/obiect/camp

 class ComplexNum {
 float Re; // camp (field)
 float Im; // camp (field)
}
 Similar cu struct, doar ca membrii (campurile) sunt vizibili privat, nu public.
 Clasa este forma (forma rectangulara),

 Obiectul este instanta (o prajitura alba-ca-zapada in exemplu)


C1- OOP – clasa: metoda

 class ComplexNum {
 float Re; // camp (field)
 float Im; // camp (field)
 void print() { printf("(%d,%d)", Re, Im); } // metoda
}
 Similar cu struct, doar ca membrii (campurile) sunt vizibili privat, nu public.
C1-C++ API

 #include <iostream>
 cin >> var; // cin este obiect, iar >> este un operator (de intrare)
 cout << var; // cout este obiect, iar << este alt operator (de iesire)
C2- OOP – clasa/obiect/camp

 Clasa:
 definitie de obiecte de acelasi tip (de aceeasi clasa)
 descrie atributele statice si comportamentele comune obiectelor de tipul clasei
 Instanta:
 o realizare a unui element de tipul clasei (obiect)
 toate instantele unei clase au proprietati simulare (descrise in definitia clasei)

 Clasa este forma (forma rectangulara),

 Obiectul este instanta (o prajitura alba-ca-zapada in exemplu)


C2- OOP – clasa: domenii de vizibilitate

 public: camp/metoda vizibila de oriunde (default pentru struct)


 protected: camp/metoda vizibila din clasa respectiva si cele derivate din ea
 private: camp/metoda vizibila doar din clasa respectiva (default pentru class)
 Exemple in CLion
C2- OOP – clasa: constructori
 Oricati constructori (functii cu NumeleClasei)
 Alocare memorie
 Populare campuri cu valori primite ca params
 Exista un constructor implicit, fara parametri, daca nu se expliciteaza unul. Daca se expliciteaza,
cel implicit se sterge automat.
 Exista tipuri speciale de constructori: de copiere, de mutare
 NB: Exista o diferenta intre operatorul de atribuire si cel de copiere/mutare

 class ComplexNum {
 float Re; // camp (field)
 float Im; // camp (field)
 public:
 ComplexNum() { Re = 0; Im = 0;} // constructor explicit, fara parametri
 ComplexNum(float r, float i) { Re = r; Im = i;} // constructor explicit, cu doi parametri float
 }
C2- OOP – clasa: destructor

 Oricati constructori (functii cu NumeleClasei)


 Un singur destructor, marcat cu ~NumeleClasei
 Dealocare memorie alocata dinamic
 Inchidere fisiere/resurse

 class ComplexNum {
 float Re; // camp (field)
 float Im; // camp (field)
 public:
 ComplexNum(float r, float I) { Re = r; Im = I;}
 ~ComplexNum () {};
 }
C4- OOP – referinte

 Referinta == un alt nume pentru aceeasi variabila deja existenta


int a = 5;
int &altnume = a; // referinta la a
const int& altaltnume = a;
Motivul:
 pentru performanta (parametru de functie)
 void reductionadd(vector_de_complex va) {}; // se pune pe stiva copie a vectorului
 void reductionadd(vector_de_complex& va) {}; // se transmite direct vectorul
 pentru usurinta in folosire (parametru de functie)
 void increment(Complex a) {a++;} // se face copie pe stiva, si se modifica doar copia
 void increment(Complex& a) {a++;} // se face modifica var din functia care cheama increment
 pentru performanta fara a putea modifica continutul se foloseste const reference
 void reductionadd(const vector_de_complex& va) {}; // se transmite direct vectorul
C4- OOP – supraincarcare operatori
 Supraincarcare (overloading) == mai multe functii cu acelasi nume, pentru a da un sens special (e.g. pentru clasele create de noi) fara a
schimba sensul general
 Pas1: Se cauta semnatura operatorului dorit
 Pas2: Se decide tipul de operator (functie membra sau exterioara clasei)
 Pas3: Se implementeaza functionalitatea dorita

 Exemplu:
// + ca free function -> T operator+( T const & lhs, T const & rhs )
 class complexf {
float Re;
float Im;

public:
complexf operator+ (const complexf &a, const complexf &b) {
complexf c;
c.Re = a.Re + b.Re;
c.Im = a.Im + b.Im;
return c;
}
 };
Semnatura operatorilor aritmetici
 Arithmetic (eg: +, -, *, /, %)
 operator+ addition
 free function -> T operator+( T const & lhs, T const & rhs )
 member function -> T operator+( T const & rhs ) const
 operator+ unary plus
 member function -> T operator+( ) const
 free function -> T & operator+( T & value )
 operator+= addition assignment
 member function -> T & operator+=( T const & rhs )
 free function -> T & operator+=( T & lhs, T const & rhs )
 operator++ increment
 member function -> T & operator++( ) -> prefix ++T
 member function -> T operator++( int ) -> postfix T++
 free function -> T & operator++( T & value ) -> prefix ++T
 free function -> T operator++( T & value, int ) -> postfix T++
Semnatura operatorilor pe biti
 Bitwise (<<, >>, &, |, ^, ~…)
 operator<< left shift
 free function -> T operator<<( T const & lhs, size_t pos )
 member function -> T operator<<( size_t pos ) const
 operator<<= left shift assignment
 free function -> T & operator<<=( T & lhs, size_t pos )
 member function -> T & operator<<=( size_t pos )
 operator| or operator bitor bitwise or
 free function -> T operator|( T const & lhs, T const & rhs )
 member function -> T operator|( T const & rhs ) const
 operator|= or operator or_eq bitwise or assignment
 free function -> T & operator|=( T & lhs, T const & rhs )
 member function -> T & operator|=( T const & rhs )
 operator~ one's compliment or bitwise not
 member function -> T operator~( ) const
 free function -> T operator~( T const & value )
Semnatura operatorilor logici
 Logical (==, !=, <, <=, >, >=, &&, ||, !, <=>)
 operator== equality
 free function -> bool operator==( T const & lhs, T const & rhs )
 member function -> bool operator==( T const & rhs ) const
 operator< less than
 free function -> bool operator<( T const & lhs, T const & rhs )
 member function -> bool operator<( T const & rhs ) const
 operator&& or operator and logical and
 free function -> bool operator&&( T const & lhs, T const & rhs )
 member function -> bool operator&&( T const & rhs ) const
 operator! or operator not logical not
 member function -> bool operator!( ) const
 free function -> bool operator!( T const & value ) const
 operator<=> spaceship operator
 See documentation on cppreference
Semnatura altor operatori
 operator-> member access
 member function -> T * operator->( )
 member function -> T const * operator->( ) const also T * is normal
 operator* dereference
 member function -> T & operator*( )
 member function -> T const & operator*( ) const
 operator[] subscript
 member function -> T & operator[]( size_t pos )> pos can be any single argument type
 member function -> T const & operator[]( size_t pos ) const> pos can be any single argument type
 operator<< stream insertion
 free function -> std::ostream & operator<<( std::ostream & os, T const & value )
 operator>> stream extraction
 free function -> std::istream & operator>>( std::istream & is, T & value )
 operator new or operator new[]
 operator delete or operator delete[]
C5-const qualifier
 const int a = 0; // valoare intreaga constanta, nu i se poate modifica valoarea
 const int* pa = &a; // pointer la constanta: valoarea pointerului se poate modifica, dar
nu si valoarea variabilei spre care se uita pointerul
 int b = 5; // variabila int
 int* const cpb = &b; // pointer constant la o variabila
 const int* const capa = &a; // pointer constant la constanta

 const – cuvant cheie care marcheaza ca constant:


 Obiecte, cu sensul ca nu i se poate atribui o alta valoare, si nu se poate chema prin el, o
metoda nemarcata ca const
 Tinta unui pointer cu sensul ca destinatia nu poate fi modificata
 Tipuri, cu sensul ca
 Metode, cu sensul ca nu face modificari asupra datelor, si metoda se poate chema prin
obiecte constante (cuvantul cheie this este pointer constant la constante)
C5-copy constructor
 Constructorul de copiere: functie membra care initializeaza un obiect, folosing un alt obiect din
aceeasi clasa
 Exista implicit daca nu se expliciteaza
 Are semnatura: NumeClasa(NumeClasa& t);

 class ComplexNum {
 float Re; // camp (field)
 float Im; // camp (field)
 public:
 ComplexNum() { Re = 0; Im = 0;} // constructor explicit, fara parametri
 ComplexNum(float r, float i) { Re = r; Im = i;} // constructor explicit, cu doi parametri float
 ComplexNum(ComplexNum& other) {
Re = other.Re;
Im = other.Im;
} // constructor de copiere
 }
C5- copy assignment operator
 Operatorul de copy-assignament

 class ComplexNum {
 float Re; // camp (field)
 float Im; // camp (field)
 public:
 ComplexNum(float r=0, float I=0) { Re = r; Im = i;} // constructor explicit, cu doi parametri float
 ComplexNum(ComplexNum& other) {
Re = other.Re;
Im = other.Im;
} // constructor de copiere
ComplexNum& operator=(const ComplexNum& t) // << copy assignment operator
{
Re = t.Re; Im = t.Im;
return *this;
}
 }
Regula celor trei:

 Daca o clasa defineste unul dintre:


 Destructor
 Constructor de copiere
 Operator de asignare
 atunci este recomandat sa le defineasca pe toate.
Copy constructor vs copy
assignament
 Cand se foloseste unul cand este folosit celalalt ?
 Exemplu Clion:

 Integer a, b;
 Integer c = a; // apel constructor copiere
 b= a; // apel operator de asignare
Templates
 Template: un mod de a scrie generic (fara a explicita tipul de date)
cod de:
 functii (template functions)
 clase (template classes)
Templates
 Functii de tip template:
 template <typename T> T myMax(T x, T y)
 {
 If (x > y) return x;
 else return y;
 }
 // functia compileaza daca exista operatorul ">" pentru orice call de
tipul:
 int a = myMax<int>(3,4); // max de integer
 double da = myMax<double>(3.4, 5.6); // max de double
Templates
 Clase de tip template:
 class <typename T> ComplexNum {
 T mRe;
 T mIm;
 public:
 ComplexNum (T re, T im) { mRe = re; mIm = im;}
 T getRe() { return mRe;}
 T getIm() { return mIm;}

 }
 int main() {
 ComplexNum<int> a(0, 0); // creare obiect din clasa cu int
 ComplexNum<double> b(0.3, 9.6); // creare obiect din clasa cu double
 }
Templates – Exemple din C++ STL
 std::vector<T> // implementeaza un tablou de acelasi tip de date
 std::set<T> // implementeaza multimea
Namespaces
 Spatii de nume:
 Un mod de a ierarhiza clasele / metodele / variabilele
 Pot exista clase cu acelasi nume, dar in spatii de nume diferite
 namespace thisspace {
 // code declarations i.e. variable (int a;)
 // method (void add();)
 // classes ( class student{};)
 };

 Cel mai folosit pana acum:


 std, unde gasim std::vector
Namespaces
 Alt exemplu de declarare clase:
namespace MySpace1 {
class ComplexNum {...};
};
namespace MySpace2 {
class ComplexNum {...};
};

 Se poate indica compilatorului sa caute si in acel spatiu de nume:


 using namespace NAMESPACE;
 Se pot folosi clasele prin FQN (fully qualified name)
 MySpace1::ComplexNum a(0,3); // obiect din clasa care este in MySpace1
 MySpace2::ComplexNum b(4,5); // obiect din clasa care este in MySpace2
C7-Inheritance (mostenire /derivare)
 Mostenirea: proces/mecanism prin care trasaturile parintilor se imprima
copiilor
 Mostenirea in OOP: mecanism prin care metode si campuri ale clasei
parinte se regasesc si in clasele copii

 Clasa parinte == super-clasa == clasa de baza


 Clasa copil == sub-clasa == clasa derivata

 Este un mecanism de baza al OOP prin care se asigura reuzabilitatea


codului deja scris
C7-Inheritance (mostenire /derivare)
 Mostenirea in OOP: mecanism prin care metode si campuri ale clasei
parinte se regasesc si in clasele copii

 Mostenirea in C++:
- Simpla (o clasa este derivata dintr-o singura alta clasa)
- Multipla (o clasa este derivata din mai multe clasa simultan)
C7-Inheritance (mostenire /derivare)
 Mostenirea in OOP: mecanism prin care metode
si campuri ale clasei parinte se regasesc si in
clasele copii

 Exemplu de mostenire in C++: Puma


 class Puma {...}; // clasa de baza
 class Cheetah : [TIP_MOSTENIRE] Puma { …}
 class Cougar : [TIP_MOSTENIRE] Puma { …}
Cheetah Cougar
C7-Inheritance (mostenire /derivare)
 Mostenirea in OOP: mecanism prin care metode si campuri ale clasei
parinte se regasesc si in clasele copii

 class Om {
 private:
 int mVarsta;
 public:
 int getVarsta();
 Om() {…} // constructor explicit, poate lipsi

 };
 class Student : public Om {
 public:
 Student() : Om() { … }

 }
C7-Inheritance (mostenire /derivare)
 Mostenire si constructori / destructori:
 Orice obiect de clasa derivata, contine un obiect de clasa de baza in el
 Deci:
 Om* om = new Student(); // ok;
 Student* stu = new Om(); // not ok;
 Cum se cheama constructorii (daca fabricam obiect de clasa derivata) ?
 Mai intai se fabrica un obiect de clasa de baza
 Apoi se fabrica obiectul de clasa derivata
 Cum se cheama destructorii (daca distrugem un obiect de clasa derivata) ?
 Mai intai se cheama destructorul obiectului de clasa derivata
 Apoi se cheama destructorul obiectului de clasa de baza
C7-Inheritance (mostenire /derivare)
 clasa abstracta pura == clasa cu metode care sunt toate pure virtuale
 clasa abstracta == clasa care are metode pure virtuale, dar si alte metode

 Nu exista obiecte de clasa abstracta (clasa nu se poate instantia); se foloseste doar pentru mostenire
 Daca dorim sa suprascriem o metoda din clasa de baza, in clasa derivata, atunci trebuie sa o declaram
virtuala
 Daca metoda nu are implementare in clasa de baza, metoda se numeste virtuala pura (daca are
implementare, se numeste doar virtuala)

 Exemplu:
 class DataInterface {
 public:
 virtual DATA getData() = 0; // fara implementare, deci e virtuala pura
 virtual void putData(DATA) { … }; // cu implementare, deci e virtuala

 };
 class USB_DI : public DataInterface {
 DATA getData() { ... cod pentru trasfer pe USB ...}
 Void putData(DATA) { … cod pentru transfer pe USB …}
};
C7-Inheritance (mostenire /derivare)
 class DataInterface {
 public:
 virtual DATA getData() = 0; // fara implementare == metoda virtuala pura
 virtual void putData(DATA) = 0; // fara implementare == metoda virtuala pura

 }; // << cod scris in 1989


 class USB_DI : public DataInterface {
 DATA getData() { ... cod pentru trasfer pe USB ...}
 void putData(DATA) { … cod pentru transfer pe USB …}
}; // << cod scris in 1996
 class NFC_DI : public DataInterface {
 DATA getData() { ... cod pentru trasfer pe NFC...}
 void putData(DATA) { … cod pentru transfer pe NFC …}
 }; // cod scris in 2004

 int main() {
 DataInterface *di;
 if (desired_interface == "usb") di = new USB_IF();
 else if (desired_interface == "nfc") di = new NFC_IF();
 di->putData(DATA); // pot cere transfer pe orice interfata (inca neinventata) cu codul scris in 1989
 POLIMORFISM == mecanismul prin care se cheama o metoda a clasei derivate printr-un pointer la clasa de baza
Exceptii
 Mecanism de tratare a erorilor care pot aparea la rulare
 O intrerupere a flow-ului normal de rulare

 Cuvinte-cheie:
 throw: arunca o exceptie din acest loc
 try: incepe o sectiune care poate arunca exceptii
 catch: prinde exceptiile aruncate in try
 noexcept (operator care certifica la compile-time ca functia nu arunca exceptii)

 Avantaje:
 Separarea codului normal de cel de tratare de erori
 Propagarea erorilor in sus, pe stiva de call-uri
 Gruparea erorilor dupa tipul lor
Exemplu (fara exceptii)
 readFile {
 open the file;
 determine its size;
 allocate that much memory;
 read the file into memory;
 close the file;
 }

 Ce se poate intampla rau?


 fisierul nu se poate deschide
 lungimea fisierului nu se poate determina
 nu se poate aloca memorie
 nu se poate citi (cauze fizice)
 nu se poate inchide fisierul
Exemplu (fara exceptii, cu tratare erori)
errorCodeType readFile {

initialize errorCode = 0;

open the file;

if (theFileIsOpen) {

determine the length of the file;

if (gotTheFileLength) {

allocate that much memory;

if (gotEnoughMemory) {

read the file into memory;

if (readFailed) {

errorCode = -1;

} else {

errorCode = -2;

} else {

errorCode = -3;

}
Exemplu (cu exceptii)
readFile {
try {
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
} catch (fileOpenFailed) {
doSomething;
} catch (sizeDeterminationFailed) {
doSomethingElse;
} catch (memoryAllocationFailed) {
doSomethingElse2;
} catch (readFailed) {
doSomethingElse3;
} catch (fileCloseFailed) {
Exceptii in C++
try {
// Block of code to try
throw exception; // Throw an exception when a problem arise
}
catch (Exception& ex) {
// Block of code to handle errors
}

try {
int heightcm = 150;
if (heightcm >= 140) {
cout << "Access granted - you are tall enough.";
} else {
throw 505;
}
}
catch (...) { // catch all exceptions
cout << "Access denied - you must have a height of at least 140cm \n";
}
Exceptii standard in C++
Ierarhia claselor pentru exceptiile standard din C++:
std::exception
- logic_error (se putea detecta daca se rulau preconditiile)
-domain_error
-invalid_argument
-length_error
-out_of_range
- runtime_error (nu se putea detecta daca se rulau preconditiile)
- range_error
- overflow_error
- underflow_error
Exceptii in C++
Cum putem crea o exceptie? Derivam din std::exception!
Metode uzuale:
- constructor fara parametri
- constructor cu std::string (eg. mesaj de eroare)
- constructor cu char* (eg. mesaj de eroare)
- virtual const char* what() const noexcept // intoarce sir de caractere cu
eroarea intampinata
Exemple:
class MyException1 : public std::exception {};
class MyException2 : public std::exception { const char* what() { return "OPAAAaaa";}};
void runRiskyCode() { .. throw MyException2();}
int main() {
try {
runRiskyCode();
}
catch (MyException2& ex) { … }
REGEX
 O expresie regulara sau REGEX este o expresie care contine o secventa de
caractere ce definesc:
 Un pattern de cautare (pentru cautari de stringuri, find/replace)
SAU
 Un pattern de validare (input validation)
Regex cheatsheet
REGEX in C++ (example)
 #include <iostream>
#include <regex>

int main() {
std::string listofwords[] = { "anagrama", "anapoda", "ananie", "anatema",
"bloc", "bara", "brandusa",
"caiet", "cartier48", "camera", "canto", "cantec" };
std::regex myregex("[b-z]*");
for (std::string str : listofwords)
if (std::regex_match(str.c_str(), myregex))
std::cout << str << std::endl;

return 0;
}

 //Output:
bloc
C++ File IO class hierarchy
C++ File I/O
 FILES
 Text files (a-z,A-Z,0-9... => characters forming words) (ios::out sau ios::in)
 Binary files (full set of ascii chars) // ios::binary + ios::out sau ios::in

 #include <fstream>
 std::ofstream (pentru scriere/output)
 std::ifstream (pentru citire/input)
 Methods for files:
 close
 >> and << operators // for text files
 getline // for text files
 read, write // for binary files
 tellg, seekg (get and set the file-read or write pointer)
Reading files

 Example for text files:


 std::string str;
 std::ifstream fin("fisierdeintrare.txt")
 while (fin >> str)
 cout << str;

 std::ofstream fout("fisierdeiesire.txt")
 fout << str;
Reading/Writing binary files

 Example for text files:


 ifstream rf("bin.dat", ios::in| ios::binary);
 rf.read((char*)&variable, sizeof(variable));

 ofstream wf("bin.dat", ios::out | ios::binary);


wf.write((char *) &variable, sizeof(variable));
Threading in C++ => threads

void toRunInParallel(param)
{
Statements;
}

int main() {
std::thread thread_obj(toRunInParallel, params);
thread_obj.join(); // wait for thread to finish
}
Threading in C++ => example

(1) Write an example to show parallel run of multiple threads


(2) Write an example for multiple threads running prime-number decomposition
Threading in C++ => mutex

MUTual EXclusion (mutex):


- Class that protects "critical section"
- A synchronization mechanism

Has 2 important methods:


lock(); // to aquire exclusive right of handling critical section
unlock();// to release the right
Threading in C++ => example

(1) Write an example to show parallel run of multiple threads (order not just computation)
(2) Write an example for multiple threads running prime-number decomposition
(3) Write (1) with correct output to console

S-ar putea să vă placă și