Sunteți pe pagina 1din 208

ACADEMIA DE STUDII ECONOMICE

Facultatea de Cibernetică, Statistică şi Informatică Economică

PROGRAMARE
ORIENTATĂ OBIECT
ÎN C++

CONF. DR. CĂTĂLIN BOJA


CATALIN.BOJA@IE.ASE.RO
ATENTIE ! SCOPUL ACESTUI DOCUMENT
ESTE DE A STRUCTURA SI DE A PREZENTA
PE SCURT NOȚIUNILE DISCUTATE LA
CURS.
ÎNVĂȚAREA MATERIEI, EXCLUSIV PE
BAZA ACESTUI MATERIAL, REPREZINTĂ O
ABORDARE SUPERFICIALA.

2008 – 2018 © Catalin Boja 2


OBIECTIVE ȘI EVALUARE

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ă

2008 - 2018 catalin.boja@ie.ase.ro 3


CUPRINS

• 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

2008 – 2018 © Catalin Boja 4


BIBLIOGRAFIE

• 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

2008 – 2018 © Catalin Boja 5


REGULI GENERALE

• Trebuie să scrieți o mulțime de programe C ++ - să testați toate


conceptele pe care le citiți, vedeți și auziți
• Generarea de erori în timpul dezvoltării este calea recomandată
pentru a învăța - remediați-le și înțelegeți de ce le-ați generat
• Nu scrieți numai programe perfecte
• Toate temele și testele sunt individuale
• Copierea la orice activitate (teme, teste, proiect, examen) vă poate
exmatricula, dar cu siguranță vă va anula toate punctele de
laborator

2008 – 2018 © Catalin Boja 6


DE CE ORIENTAT OBIECT

• 3 cuvinte magice: Încapsulare, Moștenire, Polimorfism


• Conceptele se regăsesc în toate limbajele pur obiectuale
(platforma .NET - C#, Java, Kotlin, C++, Python,
Objective-C) sau bazate pe obiecte (JavaScript)
• Unul dintre top 5 limbaje de programare de multă vreme
https://www.tiobe.com/tiobe-index/

2008 – 2018 © Catalin Boja 7


DE CE ORIENTAT OBIECT ?

Pentru că totul este


despre abstractizare
Să iei un scenariu real și să îl transpui în cod

2008 – 2018 © Catalin Boja 8


DE CE C++

• 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

• Obiecte • Sintaxa C++


• Clase
• Moștenire
• Încapsulare
• Ierarhii de clase
• Abstractizare
2008 – 2018 © Catalin Boja 10
DE CE C++

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/

2008 – 2018 © Catalin Boja 12


DE CE C++

2008 – 2018 © Catalin Boja 13


A ÎNVĂȚA SĂ CODEZI

• Să înveți să codezi se bazează pe numeroase eșecuri (…și frustrări)


• trebuie să încercați să rezolvați singuri diferite probleme folosind C ++ (după ce
crezi că ai înțeles conceptul) iar acest lucru va duce la o mulțime de eșecuri
• rezolvând toate problemele (chiar dacă durează............uneori prea mult) te va
ajuta să înveți

• 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

• Nu vă înșelați pe voi si pe ceilalți (Don’t cheat)


CUM SE ÎNVAȚĂ

“We learn wisdom from failure much more than from


success. We often discover what will do, by finding out what
will not do; and probably he who never made a mistake
never made a discovery”
― Samuel Smiles, The Lives Of George And Robert
Stephenson
A ÎNVĂȚA SĂ CODEZI…..ÎN C++ ȘI
ALTELE

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

• Nu sunt implementate individual suficiente programe C++ in Visual Studio


• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu sunt implementate individual suficiente programe C++ in Visual Studio
• Nu am înțeles conceptele

2008 – 2018 © Catalin Boja 17


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

2008 – 2018 © Catalin Boja 18


CAUZE PENTRU A NU REUȘI

Erori la execuție (run-time)


• Generate de greșeli în
implementarea logică a programului
• >99% deoarece …… memory
management defectuos (pointeri,
heap, stack, alocare, dezalocare, etc)
• Greu de identificat și corectat…..se
folosește debuggerul
• Au legătură cu complexitatea
programului, algoritmul folosit, etc

2008 – 2018 © Catalin Boja 19


REȚETA SUCCESULUI

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ă

2008 – 2018 © Catalin Boja 20


CE URMEAZĂ
Java

Anul 2 SDD – C (pointeri si


management memorie)

PAW – .NET C#

POO - C++
DAM – Java
Android

TW –
React/Angular
Anul 3

AD - Python

CTS - Java

2008 – 2018 © Catalin Boja 21


CURS 1 – INSTRUMENTE (IDE)

Microsoft Visual Studio 2017 Eclipse CDT

https://www.visualstudio.com/downloads/ https://eclipse.org/cdt/
Varianta free Community Edition este ok

2008 – 2018 © Catalin Boja 22


CURS 1 – DE RECAPITULAT

1. Tipuri de date în C (dimensiune si valori posibile)


2. Reprezentare hexazecimală și binara
3. Metode/Funcții/Subprograme (definire si apel)
4. Cel puțin un algoritm pentru sortare
5. Cel puțin un algoritm pentru căutare
6. Utilizare VS 2017/2015 (editare, compilare, rulare,
depanare)

2008 – 2018 © Catalin Boja 23


CURS 1 – RECAPITULARE NOȚIUNI C

• Pointeri (pointeri către valori, vectori dinamici


și statici, șiruri de caractere)
• Pointeri la funcții
• Referințe
• Funcții (Transferul parametrilor)
• Preprocesare
2008 – 2018 © Catalin Boja 24
POINTERI Reprezentare ASM Cod Masina
.model small B8 02 00 8E D8 A0
Sursa C/C++ .stack 16
00 00 02 06 01 00
.data
a db 7 A3 02 00 B8 00 4C
#include<stdio.h> b db 9 CD 21 00 00
c dw ? 00…..00 00 07 09
void main() .code
{ start:
char a = 7, b = 9; mov AX, @data
short int c; mov DS, AX
c = a+b; mov AL,a
} add AL,b
mov c,AX

MicroProcesor RAM mov AX, 4C00h


int 21h
end start
BUS
2008 – 2018 © Catalin Boja 25
Sursa C/C++
POINTERI #include<stdio.h>

void main()
{
char a = 7, b = 9;
short int c;
c = a+b;
MicroProcesor RAM
}

BUS

1Byte HDD

1Byte 20 Bytes 16 Bytes


B8 02 00 8E D8 A0 00 00 02 06 01 00 A3 02 00 B8 00 4C CD 21
7 9 ?
DATE COD STIVA
2008 – 2018 © Catalin Boja 26
POINTERI

• date numerice utilizate pentru a gestiona valori reprezentând adrese;


• dimensiune data de arhitectura procesorului
• definire:
tip_data * nume_pointer;
• inițializare:
nume_pointer = & nume_variabila;
• utilizare:
nume_variabila = * nume_pointer;

2008 – 2018 © Catalin Boja 27


POINTERI

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;

2008 – 2018 © Catalin Boja 28


POINTERI

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

int* const p; // pointer constant la int


int const *pint; // pointer la int constant
const int* pint2; // pointer la int constant
const int* const pint2; // pointer constant la int
// constant

char* strcpy(char p, const char *q);

2008 – 2018 © Catalin Boja 30


POINTERI – ALOCARE MEMORIE

Alocare dinamica memorie


• operatorul new sau new[ ];
• rezerva memorie in Heap
Dealocare memorie
• operatorul delete sau delete[ ];
• eliberează memoria rezervata in Heap
2008 – 2018 © Catalin Boja 31
REFERINȚA

• reprezintă un pointer constant ce este dereferit automat la


utilizare
• utilizată pentru a defini parametrii unui subprogram
int vb = 10 ;
int & refvb = vb ; // r si i refera acelasi int
int x = refvb ; // x = 10
refvb = 20 ; // vb = 20
int & ref; // EROARE definire referinta
refvb ++; // vb = 21
int * pvb = & refvb; // pvb este initializat cu adresa lui vb

2008 – 2018 © Catalin Boja 32


POINTERI LA FUNCȚII

• definire:
tip_return (* nume_pointer) (lista parametrii);

• inițializare:
nume_pointer = nume_functie;

• apel funcție prin pointer:


nume_pointer (lista parametrii);

2008 – 2018 © Catalin Boja 33


POINTERI LA FUNCȚII

• pointer la funcție ce primește un pointer la int si ce returnează


un float
f l o a t (*f p )(int *);
• funcție ce primește char* si returnează un pointer la int
i n t * f (c h a r *);
• vector de 5 pointeri la funcții ce primesc char* si returnează
un pointer la int
i n t * (*f p [5]) (c h a r *);

2008 – 2018 © Catalin Boja 34


PREPROCESARE

• Etapa ce precedă compilarea


• Bazata pe simboluri definite prin #
• NU reprezintă instrucțiuni executabile
• Determina compilarea condiționată a unor instrucțiuni
• Substituire simbolica
• Tipul enumerativ
• Macrodefinitii

2008 – 2018 © Catalin Boja 35


PREPROCESARE - SIMBOLURI

• definite cu directiva #define


#define
NMAX 1000
then
#define #define BEGIN {
#define END }

void main()
BEGIN
int vb = 10;
int vector[NMAX];
if(vb < NMAX) then printf(“mai
mic”);
else printf(“mai mare”);
END

2008 – 2018 © Catalin Boja 36


PREPROCESARE – SIMBOLURI

• valabilitate simbol: #define NMAX 1000


• sfârșit sursă; ….
• redefinire simbol;
#define NMAX 10
• invalidare simbol:

#undef NMAX

2008 – 2018 © Catalin Boja 37


PREPROCESARE – ENUM

Tipul enumerativ:
enum denumire {lista simboluri} lista variabile

• valorile sunt în secvență


• se poate preciza explicit valoarea fiecărui simbol

enum rechizite {carte, caiet, creion = 4,pix = 6, creta}

2008 – 2018 © Catalin Boja 38


PREPROCESARE – MACRODEFINIȚII

#define nume_macro(lista simboluri) expresie

Exemplu:

#define PATRAT(X) X*X


#define ABS(X) (X) < 0 ? – (X) : (X)

2008 – 2018 © Catalin Boja 39


PREPROCESARE – MACRODEFINIȚII

Macrodefinitii generatoare de funcții:

#define SUMA_GEN(TIP) TIP suma(TIP vb2, TIP vb2) \


{ return vb1 + vb2; }

2008 – 2018 © Catalin Boja 40


PREPROCESARE – MACRODEFINIȚII

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)

2008 – 2018 © Catalin Boja 43


CLASE

• reprezintă structuri de date ce incorporează date si funcții;


• permit dezvoltarea de noi tipuri de date – ADT (Abstract Data
Types);
• permit gestiunea programelor foarte mari;
• facilitează reutilizarea codului;
• permit implementarea conceptelor POO – încapsulare,
polimorfism (“o interfață, metode multiple”), moștenire

2008 – 2018 © Catalin Boja 44


CLASE

• fiecare obiect conține date (atribute/campuri) definite in clasa;


• clasa definește o serie de funcții (metode/operatii) ce pot fi aplicate
obiectelor; acestea definesc interfata obiectului;
• datele sunt ascunse in obiect si pot fi accesate numai prin funcții
definite in clasa – incapsulare;
• obiectele sunt create prin instantierea clasei;
• prin abstractizare (definire clasa) se decide ce atribute si ce metode
sunt suportate de obiecte;
• starea obiectului este definita de atributele sale;
• comportamentul obiectului este definit de metodele sale;
• termenul de passing a message către un obiect este echivalent cu
invocarea metodei;
2008 – 2018 © Catalin Boja 45
CLASE

Sintaxa definire:
class Nume_Clasa
{
tip_acces:
atribute;
functii membre;
tip_acces:
atribute;
functii membre;
};

2008 – 2018 © Catalin Boja 46


CLASE

tip_acces: class Test


{
• descrie tipul de acces la
public:
atributele si metodele

clasei;
private:
• zona de acoperire se

încheie cu definirea unui alt
public:
tip de acces sau cu

terminarea clasei;
}

2008 – 2018 © Catalin Boja 47


CLASE – TIP ACCES

• 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;

2008 – 2018 © Catalin Boja 48


CLASE – ATRIBUTE

• definesc starea obiectului;


• sunt inițializate prin instanțierea obiectului;
• prin prisma încapsulării, sunt definite in zona privata si
sunt accesate prin intermediul metodelor publice;
• definesc spațiul de memorie ocupat de o instanță a clasei
(excepție: atributele statice)
• tipuri particulare: constante, statice;
2008 – 2018 © Catalin Boja 49
CLASE – ATRIBUTE CONSTANTE

• NU este permisa modificarea valorii odată ce au fost


inițializate;

class Test
{
public:
const int atribut_1;
const char atribut_2;
}
2008 – 2018 © Catalin Boja 50
CLASE – ATRIBUTE CONSTANTE

• inițializare doar prin lista de inițializări a


constructorului:
class Test
{
public:
Test( …, int val_at_1):atribut_1(val_at_1), atribut_2(5)
{

}
};

2008 – 2018 © Catalin Boja 51


CLASE – ATRIBUTE STATICE

• definesc atribute ce nu aparțin unui obiect;


• sunt folosite de toate obiectele clasei;
• reprezintă “variabile globale” ce aparțin unei clase de
obiecte;
• declararea atributului static NU reprezintă o definire de date
(este doar o descriere);
• ATENTIE la inițializare (in funcție de scopul utilizării atributului
static)

2008 – 2018 © Catalin Boja 52


CLASE – ATRIBUTE STATICE

class Test
{
public:
static int vb_1;
static char vb_2;
};
2008 – 2018 © Catalin Boja 53
CLASE – ATRIBUTE STATICE

• definirea se realizează in zona globala folosind specificatorul


de clasa (Nume_clasa ::)

class Test
{
public:
static int vb_1;
};
int Test:: vb_1;

2008 – 2018 © Catalin Boja 54


CLASE – POINTERUL THIS

• pentru o clasa Test, acest pointer este de tipul Test *;


• reprezintă adresa obiectului care apelează metoda
membra a clasei;
• toate funcțiile membre clasei primesc implicit acest
pointer;
• se plasează pe prima poziție in lista de parametrii a
metodei;

2008 – 2018 © Catalin Boja 55


CLASE – FUNCȚII MEMBRE

• definesc interfața obiectului;


• permit accesul la atributele obiectului – încapsulare;
• definesc comportamentul obiectului;
• categorie speciala de funcții: constructor, destructor,
constructor de copiere;
• tipuri particulare: statice, inline;

2008 – 2018 © Catalin Boja 56


CLASE – FUNCȚII MEMBRE

• corpul funcțiilor poate fi definit in clasa


class Test {
void Metoda( ) { …};
};

• corpul funcțiilor poate fi definit in afara clasei folosind


specificatorul de clasa ::
class Test {
void Metoda( );
};
void Test:: Metoda( ){…};

2008 – 2018 © Catalin Boja 57


CLASE – FUNCȚII CONSTRUCTOR

• rol principal: alocarea spațiului aferent unui obiect;


• rol secundar: inițializarea atributelor obiectului;
• tipuri:
• implicit
• cu parametri
• cu parametri cu valori implicite

2008 – 2018 © Catalin Boja 58


CLASE – FUNCȚII CONSTRUCTOR

• au denumire identica cu a clasei;


• NU au tip returnat explicit deoarece returnează implicit
adresa zonei de memorie rezervata obiectului construit;
• sunt definite pe zona publică a clasei (de obicei);
• forma implicită este generată de compilator dacă nu este
definită de programator;

2008 – 2018 © Catalin Boja 59


CLASE – FUNCȚII CONSTRUCTOR

• sintaxa:
class Nume_clasa {
public:
Nume_clasa( ){…}
};
• apel:
void main () {
Nume_clasa obiect_1;
Nume_clasa obiect_2(parametrii constructor)
}

2008 – 2018 © Catalin Boja 60


CLASE – FUNCȚII 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 ) {}

2008 – 2018 © Catalin Boja 61


CLASE – FUNCȚII CONSTRUCTOR

• constructor cu parametri cu valori implicite:


Test ( int val = 0) { atribut_1 = val ; }
• sau utilizând lista de inițializări a constructorului
Test ( int val = 0) { atribut_1 = val ; }

ATENTIE. Acest tip de constructor înlocuiește formele anterioare.

2008 – 2018 © Catalin Boja 62


CLASE – FUNCȚII CONSTRUCTOR

constructor cu un parametru – caz special


class Test {
private:
int vb;
public:
Test(int z) {vb = z;}
};
void main() {
Test t = 34;
}

2008 – 2018 © Catalin Boja 63


CLASE – DESTRUCTOR

• rol principal: dealocarea spațiului aferent unui obiect;


• au denumire identica cu a clasei; pentru a se deosebi de
constructor, numele lor este prefixat de ~;
• NU au tip returnat explicit deoarece returnează implicit
void;

2008 – 2018 © Catalin Boja 64


CLASE – DESTRUCTOR

• sunt definite pe zona publica a clasei;


• forma implicita este generata de compilator daca nu este
definita de programator;
• sunt apelate implicit înainte de terminarea programului
pentru toate obiectele definite;
• pentru obiecte locale sunt executate in ordine inversa
fata de cele constructor;

2008 – 2018 © Catalin Boja 65


CLASE – DESTRUCTOR

• sintaxa:
class Nume_clasa {
public:
~Nume_clasa( ){…}
};

• apel implicit:
void main () {
Nume_clasa obiect_1;
}

2008 – 2018 © Catalin Boja 66


CLASE – DESTRUCTOR

ATENTIE ! Pentru atributele alocate dinamic in funcțiile


constructor este OBLIGATORIU dealocarea lor in
destructor. In caz contrar programul generează memory
leaks.

2008 – 2018 © Catalin Boja 67


CLASE – METODE STATICE

• definesc funcții ce nu aparțin unui obiect;


• sunt folosite de toate obiectele clasei;
• reprezintă “funcții globale” ce aparțin unei clase de obiecte;
• au acces DOAR la alți membrii statici ai clasei;
• sunt apelate prin specificatorul de clasa ::
• NU primesc in lista de parametrii pointerul THIS;

2008 – 2018 © Catalin Boja 68


CLASE – METODE STATICE

class Nume_clasa {
public:
static void Metoda_1( ){…}
};

void main( ) {
Nume_clasa::Metoda_1( );
}
2008 – 2018 © Catalin Boja 69
CLASE – METODE INLINE

• funcții scurte care nu sunt apelate;


• la compilare, apelul funcției inline este înlocuit de codul
ei, similar funcțiilor macro;
• permit execuția rapida a codului prin evitarea efortului
necesar unui apel de funcție;
• contribuie la creșterea dimensiunii codului executabil;

2008 – 2018 © Catalin Boja 70


CLASE – METODE INLINE

• implicit metodele al căror corp este definit in clasa sunt considerate


inline (NU este o regula, depinzând foarte mult de compilator);
• explicit, o metoda este definita ca inline este anunțata prin cuvântul
cheie inline;
class Test {
void Metoda( );
};
inline void Test:: Metoda( ){…};
2008 – 2018 © Catalin Boja 71
CLASE – METODE ACCESOR

• permit accesul (citire / scriere) la atributele private ale


clasei;
• presupun validarea datelor de intrare;
• sunt definite in zona publica;
• neoficial, metodele de citire sunt prefixate cu get iar cele
de modificare sunt prefixate cu set;

2008 – 2018 © Catalin Boja 72


CLASE – METODE ACCESOR

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;
}
};

2008 – 2018 © Catalin Boja 73


CLASE – TRANSFERUL PARAMETRILOR

• prin valoare (ATENȚIE la constructorul de copiere si la


operatorul =)

class Nume_clasa {

};
Nume_clasa Metoda1 (Nume_clasa
obiect);

2008 – 2018 © Catalin Boja 74


CLASE – TRANSFERUL PARAMETRILOR

• prin referință (ATENȚIE la modificări + return) ;

void Metoda2 (Nume_clasa & obiect);

• prin pointer (ATENȚIE la modificări + return) ;

void Metoda3 (Nume_clasa * obiect);

2008 – 2018 © Catalin Boja 75


CLASE – CONSTRUCTOR DE COPIERE

• rol principal: alocarea spațiului aferent unui obiect si


inițializarea acestuia cu valorile unui obiect existent;
• are forma implicita pusa de compilator ce copiază bit cu
bit valoarea obiectului existent in zona de memorie a
obiectului creat;
• este apelat automat in toate situațiile de definire +
inițializare obiect nou;
2008 – 2018 © Catalin Boja 76
CLASE – CONSTRUCTOR DE COPIERE

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;
}

2008 – 2018 © Catalin Boja 77


CLASE – CONSTRUCTOR DE COPIERE

• apel implicit: compilatorul apelează automat


constructorul de copiere pentru a copia pe stiva
subprogramului valorile obiectelor din lista de parametrii
(daca sunt trimise prin valoare);
• apel implicit: compilatorul apelează automat
constructorul de copiere pentru a copia pe stiva
programului apelator valoarea obiectului returnat de
subprogram (daca este returnat prin valoare);
2008 – 2018 © Catalin Boja 78
CLASE – CONSTRUCTOR DE COPIERE

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);
}

2008 – 2018 © Catalin Boja 79


CLASE – SUPRAÎNCĂRCARE =

• rol principal: copiază bit cu bit valoarea zonei de


memorie sursa in zona de memorie a destinației (cele
doua zone sunt identice ca structura si tip);
• in cazul obiectelor, copiază valoarea obiectului sursa in
obiectul destinație
• supraîncărcare obligatorie prin funcție membra

2008 – 2018 © Catalin Boja 80


CLASE – SUPRAÎNCĂRCARE =

• apel explicit :
class Nume_clasa {

};

void main () {
Nume_clasa obiect_1(…);
Nume_clasa obiect_2(…);
obiect_2 = obiect_1;
}

2008 – 2018 © Catalin Boja 81


CLASE – SUPRAÎNCĂRCARE =

• supraîncărcare obligatorie prin funcție membra


class Nume_clasa {
Nume_clasa operator = (Nume_clasa obiect)
{
//copiere din obiect in this;
}
};

void main () {
Nume_clasa obiect_1(…);
Nume_clasa obiect_2(…);
obiect_2 = obiect_1;
}

2008 – 2018 © Catalin Boja 82


CLASE INCLUSE

• sunt definite clase in interiorul altor clase;


class Nume_clasa_parinte {

class Nume_clasa_copil {…};
};
• declarația este vizibilă doar in interiorul clasei părinte
• accesul la clasa copil este posibilă doar prin specificatorul
clasei părinte
Nume_clasa_parinte:: Nume_clasa_copil test;
2008 – 2018 © Catalin Boja 83
CLASE – ATRIBUTUL FRIEND

• se permite accesul pe zona privata sau protected din afara clasei


(din interiorul clasei prietene);
• clasa prietenă se anunță în clasa protejată prin atributul friend
class Nume_clasa_1 {

friend class Nume_clasa_2;
};
class Nume_clasa_2 {

};

2008 – 2018 © Catalin Boja 84


CLASE – POINTERI DE ATRIBUTE

• indică “adresa” unui atribut in cadrul obiectului – offset


(deplasament);
• sintaxa definire:
tip_atribut Nume_clasa:: * nume_pointer_atribut ;
• inițializare:
nume_pointer_atribut = & Nume_clasa:: nume_atribut ;
• utilizare:
Nume_clasa obiect, *pobiect = & obiect;
tip_atribut variabila = obiect.* nume_pointer_atribut
tip_atribut variabila = pobiect->* nume_pointer_atribut

2008 – 2018 © Catalin Boja 85


CLASE – POINTERI DE METODE

• indică “adresa” unei metode in cadrul listei de funcții a clasei –


offset (deplasament);
• sintaxa definire:
tip_returnat (Nume_clasa:: * nume_pointer_metoda) (parametrii) ;

• 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)

2008 – 2018 © Catalin Boja 86


SUPRAÎNCĂRCARE FUNCȚII
(OVERLOADING)
• implementează conceptul de polimorfism (același lucru,
mai multe interpretări)
• atribuirea unui simbol (nume funcție) mai multe
semnificații;
• diferența se face in funcție de semnătura funcției =
numărul si tipul parametrilor;
• tipul returnat NU reprezintă criteriu de selecție la apel
2008 – 2018 © Catalin Boja 87
SUPRAÎNCĂRCARE FUNCȚII
(OVERLOADING)
Etape identificare forma funcție:
1. identificare forma exacta;
2. aplicare conversii nedegradante asupra
parametrilor;
3. aplicare conversii degradante asupra parametrilor;
4. aplicare conversii definite explicit de programator
prin supraîncărcarea operatorului cast;
5. generare eroare ambiguitate : overloaded function
differs only by return type from …

2008 – 2018 © Catalin Boja 88


SUPRAÎNCĂRCARE FUNCȚII
(OVERLOADING)
int suma(int a, int b)
{
return a+b;
}

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);
}

2008 – 2018 © Catalin Boja 89


SUPRAÎNCĂRCARE OPERATORI
(OVERLOADING)
operator+(t1,t2)
class Test{
… (supraîncărcare prin
}; funcție globala)
void main() interpretare
{
Test t1, t2, t3;
t1 = t2 + t3; t1.operator+(t2)
}
(supraîncărcare prin
funcție membra)
2008 – 2018 © Catalin Boja 90
SUPRAÎNCĂRCARE OPERATORI

Restricții supraîncărcare operatori:


• NU schimba precedenta operatorilor;
• NU schimba asociativitatea;
• conserva cardinalitatea (numărul parametrilor)
• NU creează operatori noi;
• formele supraîncărcate nu se compun automat;
• NU se supraîncarcă . .* :: ?:

2008 – 2018 © Catalin Boja 91


SUPRAÎNCĂRCARE OPERATORI

Restricții supraîncărcare operatori:


• supraîncărcarea se realizează prin funcții membre sau
funcții globale. EXCEPTII:
• funcție membra: ( ) [ ] -> =
• funcție globală: new delete

• NU garantează comutativitatea;
• formele post si pre sunt supraîncărcate diferit;
2008 – 2018 © Catalin Boja 92
SUPRAÎNCĂRCARE OPERATORI

Supraîncărcarea prin funcții membre sau funcții globale ?


• verificare excepție ?
• verificare tip primul parametru:
• daca are tip diferit de cel al clasei analizate atunci
supraîncarc prin funcție globala
• daca are tip identic cu cel al clasei analizate atunci aleg
funcție membra sau funcție globala

2008 – 2018 © Catalin Boja 93


SUPRAÎNCĂRCARE OPERATORI

Operatorii supraîncărcați prin funcții membre primesc pe


prima poziție ca parametru pointerul this

class Test{
Test operator+(Test t, int vb){

}
};
operator + cu 3 parametri !!!!!
2008 – 2018 © Catalin Boja 94
SUPRAÎNCĂRCARE OPERATORI

Trebuie acordata atenție la alegerea tipului returnat:


• dacă operatorul se apelează in cascadă;
• dacă returnează referințe de obiecte sa nu fie ale unor
obiecte temporare;
• dacă returnează valori de obiecte, atenție la apelurile
constructorului de copiere;

2008 – 2018 © Catalin Boja 95


SUPRAÎNCĂRCARE << ȘI >>

supraîncărcare operatori << si >> (iostream):


• operatorul << lucrează cu cout (de tip ostream &);

ostream & operator << (ostream & cout, tip_data)

• operatorul >> lucrează cu cin (de tip istream&)

istream & operator >> (istream & cin, tip_data &)

• prin funcție independenta;

2008 – 2018 © Catalin Boja 96


SUPRAÎNCĂRCARE << ȘI >>

class Test{
int info;
friend ostream& operator << (ostream &, Test);
friend istream& operator >> (istream &, Test &);
};

ostream& operator << (ostream & iesire, Test t){



iesire<<info;
return iesire;
}
istream& operator >> (istream & intrare, Test & t){

intrare>>info;
return intrare; este friend ca sa aibă acces pe
} zona privată
2008 – 2018 © Catalin Boja
NU ESTE OBLIGATORIU ! 97
SUPRAÎNCĂRCARE OPERATORI UNARI
++ ȘI -
• 2 forme: prefixată și post fixată;
• prin funcție membră sau independentă;

int vb1 = 10;


int vb2 = vb1++; -> vb2 = 10 si vb1 = 11;
int vb3 = 10;
int vb4 = ++vb3 -> vb4 = 11 si vb3 = 11

2008 – 2018 © Catalin Boja 98


SUPRAÎNCĂRCARE OPERATORI UNARI
++ ȘI - forma prefixată prin funcție
membra
class Test{

Test & operator++ ( ) {
forma postfixată prin funcție
//prelucrari
independentă
return *this;
}
friend Test operator++(Test &, int);
};
Test operator++ (Test &t, int) {
Test copie = t;
//prelucrari este friend ca sa aibă acces pe
return copie; zona privată
} NU ESTE OBLIGATORIU !
2008 – 2018 © Catalin Boja 99
SUPRAÎNCĂRCARE OPERATORI BINARI
+, -, *, /
• au întotdeauna 2 parametri;
• comutativitatea operației matematice nu are sens in
C++ (trebuie definita explicit)
• prin funcție membră sau independenta in funcție de
forma operatorului;

2008 – 2018 © Catalin Boja 100


SUPRAÎNCĂRCARE OPERATORI BINARI
+, -, *, /
• pentru forma obiect + [obiect / alt tip]:
• prin funcție membra:
class Test{

int operator+ (int vb) {…}
};
void main()
{
Test t;
int rez = t + 5; X
int rez = 5 + t;
}
2008 – 2018 © Catalin Boja 101
SUPRAÎNCĂRCARE OPERATORI BINARI
+, -, *, /
• pentru forma obiect + obiect / alt tip:
• prin funcție independentă [si friend]:
class Test{

friend int operator+ (Test,int);
};

int operator+ (Test t, int vb){…}

2008 – 2018 © Catalin Boja 102


SUPRAÎNCĂRCARE OPERATORI BINARI
+, -, *, /
• pentru forma alt tip + obiect:
• doar prin funcție independenta [si friend]:
class Test{

friend int operator+ (int, Test);
};

int operator+ (int vb, Test t){…}

2008 – 2018 © Catalin Boja 103


SUPRAÎNCĂRCARE OPERATORI BINARI
+=, -=, *=, /=
• au întotdeauna 2 parametri;
• prin funcție membra sau independenta;

class Test{

friend int operator+= (Test,int);
};

int operator+= (Test t, int vb){…}


2008 – 2018 © Catalin Boja 104
SUPRAÎNCĂRCARE OPERATOR []

• are întotdeauna 2 parametri;


• doar prin funcție membra;
• este folosit pentru a permite acces in citire / scriere
pe elementele unui sir de valori din zona privata a
obiectului;
• poate fi apelat în cascadă;
• indexul nu este obligatoriu de tip numeric;
2008 – 2018 © Catalin Boja 105
SUPRAÎNCĂRCARE OPERATOR []
class Test{
int *valori; forma care asigura doar
int nr_valori; citirea datelor !!!

int operator[ ] (int);
};

int Test::operator[ ] (int index){


if (index >=0 && index < nr_valori)
return valori[index];
else throw new exception();
}
void main(){
Test t;
int vb = t[5];
t[3] = 10; ATENTIE - EROARE !
2008 – 2018 © Catalin Boja 106
}
SUPRAÎNCĂRCARE OPERATOR []
class Test{
int *valori;
int nr_valori; forma care asigură citirea /
… modificarea datelor !!!
int& operator[ ] (int);
};

int& Test::operator[ ] (int index){


static int eroare;
if (index >=0 && index < nr_valori)
return valori[index];
else throw new exception();
}
void main(){
Test t;
int vb = t[5];
t[3] = 10;
2008 – 2018 © Catalin Boja 107
}
SUPRAÎNCĂRCARE OPERATOR CAST

• are întotdeauna 1 parametru;


• numele castului reprezintă tipul returnat;
• nu are tip returnat explicit;
• prin funcție membra;
• folosit la conversia intre diferite tipuri de date;
• ATENȚIE la apelurile implicite puse de compilator pentru a
determina semnătura unei funcții;

2008 – 2018 © Catalin Boja 108


SUPRAÎNCĂRCARE OPERATOR CAST

class Test{
int valoare;

int operator int () { return valoare;}
};
void main(){
Test t;
int vb = t; //echivalent cu vb = t.valoare;
}

2008 – 2018 © Catalin Boja 109


SUPRAÎNCĂRCARE OPERATOR !

• are un parametru;
• prin funcție membra sau independentă;

class Test{
int valoare;

void operator ! () {valoare*=-1;}
};
void main(){
Test t;
!t;
}

2008 – 2018 © Catalin Boja 110


SUPRAÎNCĂRCARE OPERATOR ,

• are doi parametri;


• prin funcție membra sau independenta;
• in mod uzual returnează valoarea ultimului parametru;

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;
}

2008 – 2018 © Catalin Boja 111


SUPRAÎNCĂRCARE OPERATOR
FUNCȚIE ()
• are număr variabil de parametri;
• prin funcție membra;
• NU creează o noua cale de apelare a unei funcții;
• se creează o funcție operator care poate primi un
număr arbitrar de parametri;

2008 – 2018 © Catalin Boja 112


SUPRAÎNCĂRCARE OPERATOR
FUNCȚIE ()
class Test{
int valoare;

int operator () (int i, int j) {
valoare = i + j;
return valoare;}
};
void main(){
Test t;
t(3,4);
int vb = 10 + t(5,10);
}

2008 – 2018 © Catalin Boja 113


CLASE – SUPRAÎNCĂRCARE ->

supraîncărcare operator ->;


• are întotdeauna 1 parametru;
• obligatoriu prin funcție membra;
• întoarce pointer spre un obiect asupra caruia opereaza;
class Test{

Test * operator-> ( ) {return *this;}
};

2008 – 2018 © Catalin Boja 114


CONVERSII INTRE OBIECTE DE DIFERITE
TIPURI
• supraîncărcarea constructorului clasei rezultat;
• supradefinirea operatorului cast al clasei sursa;
• apelurile implicite ale constructorului clasei rezultat
sunt eliminate prin atributul explicit pus la definirea
acestuia;

2008 – 2018 © Catalin Boja 115


POINTERI CONSTANȚI DE OBIECTE SI
POINTERI DE OBIECTE CONSTANTE
• definirea se face prin poziționarea atributului const in
raport cu tipul si numele pointerului;
class Test{

void Metoda const ( ) {…}
};
… Obiectul referit prin this
Test * const pConstantTest; este constant
const Test * pTestConstant1;
Test const * pTestConstant2;
2008 – 2018 © Catalin Boja 116
C++ – DERIVARE / MOȘTENIRE

• 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{
};

2008 – 2018 © Catalin Boja 117


C++ – DERIVARE / MOȘTENIRE

• prin derivare NU se elimina restricțiile de acces din clasa


de bază;

zona Baza tip derivare: zona Derivat

public public public

protected protected protected

private private private

2008 – 2018 © Catalin Boja 118


C++ – DERIVARE / MOȘTENIRE

• prin derivare NU se elimina restrictiile de acces din


clasa de baza;

zona Baza tip derivare: zona Derivat

public public public

protected protected protected

private private private

2008 – 2018 © Catalin Boja 119


C++ – DERIVARE / MOȘTENIRE

• prin derivare NU se elimină restricțiile de acces din


clasa de bază;

zona Baza tip derivare: zona Derivat

public public

protected protected inaccesibil

private private

2008 – 2018 © Catalin Boja 120


C++ – DERIVARE / MOȘTENIRE

• excepții de la tip derivare (protected sau private)


pentru anumite atribute sau metode (publice in clasa
de baza): publicizare
class Baza{
public:
int atribut1;
int atribut2;
};
class Derivat : private Baza{ ramane public in Derivat
public:
Baza::atribut1; devine private in Derivat
};
2008 – 2018 © Catalin Boja 121
C++ – DERIVARE / MOȘTENIRE

• prin derivare noua clasa primește de la clasa de


bază toate metodele + atributele
class Baza{
int atribut1;
int atribut2;
}; mostenire
class Derivat : private Baza{
int atribut_nou;
};

2008 – 2018 © Catalin Boja 122


C++ – DERIVARE / MOȘTENIRE
• fiecare constructor este responsabil strict de zona clasei
pe care o reprezintă constructor Baza
class Baza{
int atribut1;
int atribut2;
};
class Derivat : private Baza{ mostenire
int atribut_nou;
};

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.

2 – dealocare atribut !!!!!!!!


class Baza{ (mai este alocat ???)
int * spatiu();
~Baza(){delete [ ]spatiu;} 1- dealocare atribut moștenit
};
class Derivat : tip derivare Baza{
~Derivat(){delete [ ]spatiu};
};
2008 – 2018 © Catalin Boja 125
C++ – DERIVARE / MOȘTENIRE

• metode care nu se moștenesc integral: operatorul = și


Constructorul de Copiere

class Baza{
int atribut1;int atribut2;
Baza& operator=(Baza& b){…}
Baza(Baza& b) {…}
};
class Derivat : private Baza{
int atribut_nou;
};

2008 – 2018 © Catalin Boja 126


C++ – DERIVARE / MOȘTENIRE
• metode care NU se moștenesc integral: operatorul = și
Constructorul de Copiere
void main(){
Derivat d1;
d1 d2
Derivat d2;
operator = Baza
d1 = d2;

d1 d2
Derivat d3 = d1;
copiere bit cu bit
}

constructor Derivat
d3 d1

Constructor copiere din Baza


2008 – 2018 © Catalin Boja 127
C++ – DERIVARE / MOȘTENIRE

• UPCASTING – este permisă transformarea implicită a obiectelor sau


pointerilor de tip derivat în obiecte sau pointeri de tip bază

class Baza{ Baza



};
X
class Derivat : public Baza{
… Derivat
};
2008 – 2018 © Catalin Boja 128
C++ – DERIVARE / MOȘTENIRE

• 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

• pot fi definite funcții cu același header in clasa de


bază și în clasa derivată

class Baza{ void main(){


int Metoda1(int a){…} Derivat d1;
};
class Derivat : private Baza{ d1.Metoda1(5);
int atribut_nou;
int Metoda1(int a){…} d1.Baza::Metoda1(5);
}; }
2008 – 2018 © Catalin Boja 130
C++ – DERIVARE / MOȘTENIRE

• UPCASTING + redefinire metode


void main(){
Derivat d1, *pd1;
Baza b1, *pb1;
b1 d1
b1 = d1;

pd1 = &d1;
pb1 = pd1; b1 d1

b1.Metoda1(5); ÎNTODEAUNA forma


pb1->Metoda1(5); metodei din Baza;
}
2008 – 2018 © Catalin Boja 131
C++ – DERIVARE / MOȘTENIRE

UPCASTING + redefinire metode


• versiunea funcției se stabilește de la compilare (early binding)
• indiferent daca se realizează UPCASTING prin valori sau pointeri se
apelează metoda din clasa de baza
void main(){
Derivat d1, *pd1;
Baza b1, *pb1;
b1 = d1; //upcasting la nivel de obiect
pd1 = &d1; //upcasting la nivel de pointer
pb1 = pd1;
}
2008 – 2018 © Catalin Boja 132
CLASE – FUNCȚII VIRTUALE

• permit redefinirea (overriding) funcției din clasa de


baza în clasa derivată
class Baza{
virtual int Metoda1(int a){…}
};

class Derivat : private Baza{


int atribut_nou;
int Metoda1(int a){…}
};

2008 – 2018 © Catalin Boja 133


CLASE – FUNCȚII VIRTUALE

• versiunea funcției se stabilește la momentul execuției (late


binding)
• fiecare clasa conține o tabela de pointeri la funcții
virtuale;
• fiecare obiect primește un pointer la tabela de pointeri la
funcții virtuale
• daca se realizează UPCASTING prin pointeri (NU si prin
valori) se apelează metoda din clasa derivata

2008 – 2018 © Catalin Boja 134


CLASE – FUNCȚII VIRTUALE
tabela adrese functii
virtuale din Baza
& Metoda1
class Baza{
int atribut1;
int atribut2;
virtual int Metoda1(){…}
}; doar structura
NU si valoare
class Derivat : private Baza{ mostenire
int atribut_nou;
int Metoda1() {…}
};

tabela adrese functii


& Metoda1
virtuale din Derivat
2008 – 2018 © Catalin Boja 135
CLASE – FUNCȚII VIRTUALE
void main(){
Derivat d1, *pd1; INTODEAUNA forma
Baza b1, *pb1; metodei din Baza;
b1 = d1;
b1.Metoda1(5);

pd1 = &d1; forma metodei din


pb1 = pd1; Derivat pentru Metoda1
pb1->Metoda1(5);
virtuala;
}
2008 – 2018 © Catalin Boja 136
CLASE – FUNCȚII VIRTUALE

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

POLIMORFISM (același lucru, mai multe interpretări) :


• SUPRAINCARCAREA (OVERLOADING) de funcții in
cadrul unei clase
• SUPRADEFINIRE (REDEFINIRE) (OVERRIDING) de funcții
virtuale in clasele derivate

2008 – 2018 © Catalin Boja 138


CLASE – MOȘTENIRE VS COMPUNERE

se implementează când
class Vehicol{ intre clasa derivata si

};
clasa de baza exista
relația is a;
class Automobil: public Vehicol{

};

2008 – 2018 © Catalin Boja 139


CLASE – MOȘTENIRE VS COMPUNERE

class Motor{
… se implementează
}; când intre clasa
principala si cea
class Automobil{ inclusa exista o
Motor motor; relație has a;
};

2008 – 2018 © Catalin Boja 140


CLASE – DERIVARE / MOȘTENIRE
MULTIPLĂ
Proprietăți moșteniri multiple:
• constructorii se apelează in ordinea derivării;
• destructorii se apelează in ordine inversa derivării;
• ambiguități la adresarea membrilor moșteniți care se
numesc la fel in clasele de baza
• ambiguități la moștenirile din clase de baza cu o
baza comuna
2008 – 2018 © Catalin Boja 141
CLASE – DERIVARE / MOȘTENIRE
MULTIPLĂ
class Baza1{
};
class Baza2{
};

class Derivat : tip derivare Baza1, tip


derivare Baza2{
};

2008 – 2018 © Catalin Boja 142


CLASE – DERIVARE / MOȘTENIRE
MULTIPLĂ
• Derivare multiple – derivare
din mai multe clase de baza Diamond of death
• Trebuie evitata deoarece Persoana
generează multe probleme
• Este ok derivarea multipla a Student Angajat
claselor abstracte ce nu
conțin atribute
Stagiar

2008 – 2018 © Catalin Boja 143


CLASE – FUNCȚII VIRTUALE PURE

• funcții virtuale ce nu au corp definit in clasa in care sunt


anunțate
• sunt definite prin expresia

virtual tip returnat nume_functie( parametrii ) = 0;

• IMPUN redefinirea (overriding) funcției in clasa derivata


(daca nu se dorește abstractizarea clasei derivat)

2008 – 2018 © Catalin Boja 144


CLASE – FUNCȚII VIRTUALE PURE

class Baza_abstracta{
virtual int Metoda1(int a) = 0
};

class Derivat : public Baza{


int Metoda1(int a){…}
};

2008 – 2018 © Catalin Boja 145


CLASE ABSTRACTE

• clase ce conțin minim o funcție virtuală pură;


• rol de interfață pentru clase care trebuie sa definească o
serie de metode comune
• un contract intre proprietarii mai multor clase prin care se
impune definirea unor serii de metode comune;
• contractul se încheie prin derivarea din clasa abstracta;

2008 – 2018 © Catalin Boja 146


CLASE ABSTRACTE

• NU este permisă instanțierea claselor abstracte;


• utilizate ca suport pentru derivare
class Baza_abstracta{
int atribut1;
virtual int Metoda1(int a) = 0
};
void main(){
Baza_abstracta ba;
}

2008 – 2018 © Catalin Boja 147


CLASE ABSTRACTE
int NrPuncte; virtual double Perimetru()=0;
Punct * Puncte; virtual double Arie()=0;
virtual double GetNrPuncte()=0;
IMasurabil
Punct Model2D
int X;
int Y;

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

ListaModele[1] = new Cerc();


Dreptunghi
ListaModele[2] = new Patrat(); _vfptr & Cerc::Arie

& Cerc ::Perimetru

Cerc & Cerc ::GetNrPuncte

[0] [1] [2] _vfptr

& Patrat::Arie

Patrat & Patrat ::Perimetru


2008 – 2018 © Catalin Boja _vfptr
& Patrat ::GetNrPuncte149
CLASE – DOMENII DE NUME

• reprezintă o modalitate de grupare a variabilelor


globale, claselor si funcțiilor globale
• permite definirea de clase, variabile, funcții identice ca
nume dar in spatii de nume diferite
• facilitează dezvoltarea distribuita de cod deoarece
programatorii nu impun restricții de nume intre ei
• cuvânt cheie namespace
2008 – 2018 © Catalin Boja 150
CLASE – DOMENII DE NUME

• definire: • adăugare de elemente:


namespace Colectie1{ namespace Colectie1{
}; int vb1;
• definire alias: };
namespace Colectia = namespace Colectie1{
Colectia1; int vb2;
};

2008 – 2018 © Catalin Boja 151


CLASE – DOMENII DE NUME

• utilizare - prin operatorul de namespace Colectie1{


rezoluție int vb1;
};
namespace Colectie2{
int vb2;
};
void main(){
Colectie1::vb1 = 10;
Colectie2::vb2 = 20;
}

2008 – 2018 © Catalin Boja 152


CLASE – DOMENII DE NUME

• utilizare - prin directiva namespace Colectie1{


int vb1;};
using namespace
namespace Colectie2{
int vb2;};
void main(){
using namespace Colectie1;
vb1 = 10;
Colectie2::vb2 = 20;
}

2008 – 2018 © Catalin Boja 153


C++ – GESTIUNE EXCEPȚII

• excepție – situație in care prelucrarea anumitor date de


intrare nu este gestionata sau nu este posibila (ex:
împărțire la 0, citire in afara unui masiv)
• permite gestiunea situațiilor excepționale care conduc la
terminarea imediata a programului
• necesar pentru a realiza programe robuste si fiabile
• implementat prin try, catch si throw
• permite gestiunea erorilor de sistem si a erorilor definite
de programator

2008 – 2018 © Catalin Boja 154


C++ – GESTIUNE EXCEPȚII

try {
if(conditie_1) throw exceptie;
if(conditie_2) throw exceptie_generala;
}
catch(exceptie){ //secventa prelucrari}

catch(alta_exceptie) {//secventa prelucrari}

catch(…){ //secventa prelucrari generale}


2008 – 2018 © Catalin Boja 155
C++ – GESTIUNE EXCEPȚII

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

Blocurile catch sunt definite in ordine crescătoare a generalității


excepțiilor tratate
try { … }
catch(exceptie_tip_1){…}
catch(exceptie_tip_2){…}

catch(…){…}
2008 – 2018 © Catalin Boja 157
C++ – GESTIUNE EXCEPȚII

catch(…){…} poate fi înlocuită de funcția standard


apelata la tratarea unei excepții necaptate –
terminate( )

void functie_terminate(){
cout << "functie_terminate()";
exit(-1);
}
set_terminate( functie_terminate );

2008 – 2018 © Catalin Boja 158


C++ – GESTIUNE EXCEPȚII

DEFINIRE METODE (convenție, NU regula) ce arunca excepții:


• funcția anunță prin header ce excepții generează
void functie() throw(exception, DivideByZero){ …}
• funcția poate genera orice tip de excepție
void functie(){ …}
• funcția nu generează excepții
void functie() throw(){ …}

2008 – 2018 © Catalin Boja 159


C++ – GESTIUNE EXCEPȚII

• permite separarea prelucrărilor de gestiunea


erorilor;
• o noua metoda de a anunța execuția cu succes sau
nu a unei funcții (in detrimentul variabilelor globale)
• Importanță pentru gestiunea erorilor in constructori

2008 – 2018 © Catalin Boja 160


C++ – GESTIUNE EXCEPȚII

• funcția anunța o excepție iar programul apelator:


• rezolvă problema
• decide reapelarea funcției sau continuarea programului
• generează alta rezultate
• termină programul într-un mod “normal” (dealocă memoria,
salvează rezultate parțiale);
• rezolvă parțial problema si arunca o noua excepție pentru un
context superior.

2008 – 2018 © Catalin Boja 161


C++ – GESTIUNE EXCEPȚII

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

2008 – 2018 © Catalin Boja 164


C++ – GESTIUNE EXCEPȚII

2008 – 2018 © Catalin Boja 165

http://www.tutorialspoint.com/cplusplus/cpp_exceptions_handling.htm
CLASE – STREAM-URI

• STREAM – obiect ce permite gestiunea si manipularea


șiruri de baiți
• utilizate in mod obișnuit cu forma supraîncărcată a
operatorului << (inserter) si a operatorului >>
(extracter)
• obiecte standard: cout de tip ostream si cin de tip
istream, cerr (asociat stream-ului standard de erori)
2008 – 2018 © Catalin Boja 166
CLASE – STREAM-URI STANDARD

ios streambuf

istream ostream

iostream

2008 – 2018 © Catalin Boja 167


CLASE – STREAM-URI STANDARD

Formatarea datelor din stream-uri:


• metode ale obiectelor cin si cout (de exemplu width, fill)
• manipulatori (iomanip.h)
• flag-uri (biti) de formatare din clasa ios (metoda
ios::setiosflags)
• flag-uri (biti) de formatare ale obiectelor cin si cout
(metoda setf)

2008 – 2018 © Catalin Boja 168


CLASE – STREAM-URI STANDARD

• dec • setbase(int)
• hex • setfill()
• oct • setw(int)
• setprecision(int) • setiosflags(long)
• endl • resetiosflags(long)
• ends
• ws
• flush

2008 – 2018 © Catalin Boja 169


CLASE – STREAM-URI STANDARD
Flag-uri formatare (setiosflags si resetiosflags):

• 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

2008 – 2018 © Catalin Boja 170


CLASE – STREAM-URI STANDARD
Flag-uri formatare (long ios::setf(long val, long ind)):
• ios::basefield • ios::dec
• ios::hex
• ios::oct
• ios::floatfield • ios:fixed
• ios::scientific
• ios::adjustfield • ios::left
• ios::right
• ios::internal

2008 – 2018 © Catalin Boja 171


CLASE – STREAM-URI STANDARD

Citire string-uri cu cin:


• asemenea functiei scanf considera terminator de sir de caractere si spatiul
• pentru citiri speciale se folosesc metodele get si getline ale obiectului cin;

cin.getline(char* adr_buffer, int nr_bytes, int delimitator)


– extrage delimitatorul din input
cin.get(char* adr_buffer, int nr_bytes, int delimitator)

2008 – 2018 © Catalin Boja 172


CLASE – STREAM-URI STANDARD

Detectare erori la citire/scriere:


• erori semnalate prin setarea (valoare 1) unor flag-uri (biți) de stare
ai fluxurilor:
• failbit
• badbit

• flag-urile sunt testate prin metodele:


• boolean good()
• int fail()
• int bad()

• flag-urile sunt resetate prin metoda clear()

2008 – 2018 © Catalin Boja 173


CLASE – STREAM-URI STANDARD
Detectare erori la citire/scriere:
resetare flag-uri
int Cod = 0;
bool IsOk = false;
while(!IsOk){
golire buffer input
cout << "\n Cod angajat:";
cin >> Cod;
IsOk = cin.good();
if(!IsOk)
cerr<<"\n Valoare eronata pentru cod !";
cin.clear();
cin.ignore(256,'\n');
}

2008 – 2018 © Catalin Boja 174


CLASE – STREAM-URI STANDARD

Detectare erori la citire/scriere: pt erori >> returneaza NULL


int valoare;
while(cout<<"Dati o valoare sau CTRL+Z:",
cin>>valoare);

operator (,) returneaza ultima valoare

2008 – 2018 © Catalin Boja 175


C++ – LUCRU CU FIȘIERE

Intrări / Ieșiri pe fișiere nestandard:


• prin obiecte definite in fstream.h
• ifstream - lucru cu fișiere în mod citire;
• ofstream - lucru cu fișiere în mod scriere;
• fstream - lucru cu fișiere în mod citire/scriere;
• definire prin:
• constructor cu nume:
tip_fstream ob_fis( char * nume_fisier)
• prin metoda open:
ob_fis.open (char * nume_fisier, long mod_open)

2008 – 2018 © Catalin Boja 176


C++ – LUCRU CU FIȘIERE

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

Citire/Scriere din fișiere:


• prin operatorii >> si <<;
• prin metodele get( ) (returnează EOF, -1, pentru sfârșit de fișier) si
put ( ) ce lucrează la nivel de octet
• prin metodele generale read( ) (returnează NULL, pentru sfârșit de
fișier) și write( ) :

istream& istream::read(char * buffer, int nr_octeti)


ostream& ostream::write(char * buffer, int nr_octeti)

2008 – 2018 © Catalin Boja 178


C++ – LUCRU CU FIȘIERE

Citire/Scriere din fișiere:

buffer in care se citește din fișier

istream& istream::read(char * buffer, int nr_octeti)

buffer din care se scrie in fișier nr octeți de citit / scris

ostream& ostream::write(char * buffer, int nr_octeti)

2008 – 2018 © Catalin Boja 179


C++ – LUCRU CU FIȘIERE

Citire din fișiere:


• testarea sfârșitului de fișier se face si prin verificarea flag-
ului eofbit prin metoda

bool eof()

a unui obiect de tip fstream.

2008 – 2018 © Catalin Boja 180


C++ – LUCRU CU FIȘIERE

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

2008 – 2018 © Catalin Boja 182


C++ – LUCRU CU FIȘIERE

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

2008 – 2018 © Catalin Boja 184


FUNCȚII TEMPLATE

• permit creșterea gradului de generalizare prin definirea


de șabloane de funcții
• la definire se utilizează tipuri generice:

class T
typename T

• funcția este instanțiată de compilator la utilizare când tipul


generic este înlocuit de un tip concret

2008 – 2018 © Catalin Boja 185


FUNCȚII TEMPLATE

• definire:
template <typename T1, typenameT2, …>

tip_returnat nume_functie( T1 param1, T1 param2, T2


param3, … )

• inițializare & utilizare:

nume_functie <tip_concret, tip_concret, …>( param1,


param2, param3,… )

2008 – 2018 © Catalin Boja 186


FUNCȚII TEMPLATE

• definire:
template <typename T>
T aduna (T a, T b){ return a+b;}

• inițializare & utilizare:


int suma = aduna<int> (5,6);
double suma2 = aduna<double>(5.5, 6.6);

2008 – 2018 © Catalin Boja 187


CLASE TEMPLATE

• reprezintă șabloane de clase, descrieri parametrizate


de clasa;
• permit adaptare la tipuri de date concrete
(fundamentale + utilizator)
• prin instanțierea șablonului, constructorul generează
clase concrete

2008 – 2018 © Catalin Boja 188


CLASE TEMPLATE

Clase template:
template <class T1, typename T2, …, tip1 c1, tip2 c2, …>
class nume_clasa{
tip concret

}

nume_clasa<tipc1, tipc2, …, val1, val2, …> obiect;

2008 – 2018 © Catalin Boja 189


CLASE TEMPLATE

Clase template cu tip generic :


template <typename T>
class Vector{
T * valori;
int dim;
public:

};

Vector<int> v1;

2008 – 2018 © Catalin Boja 190


CLASE TEMPLATE

Clase template cu tip generic + constante:


template <typename T, int n>
class Vector_S{
T valori[n];
int dim;
public:

};

Vector<int,10> v1;

2008 – 2018 © Catalin Boja 191


CLASE TEMPLATE

Clase template cu tip generic + constante (cu valori default):


template <typename T=int, int n=5>
class Vector_S {
T valori[n];
int dim;
public:

};
Vector<int,10> v1;
Vector<> v2;
Vector<double> v2;

2008 – 2018 © Catalin Boja 192


CLASE TEMPLATE

Utilizare clase template:


Se dorește utilizarea șablonului sau a unui caz concret ?
• caz concret:
int compara(Vector<int> v1, Vector<int> v2){…}
• șablon:
template<typename T1, typename T2>
int compara(Vector<T1> v1, Vector<T2> v2){…}

2008 – 2018 © Catalin Boja 193


CLASE TEMPLATE

Utilizare clase template in librarii dinamice:


• NU se pot construi librarii dinamice (LIB, DLL) de șabloane;
• trebuie anunțate utilizări viitoare pentru a forța instanțieri
template class Vector<int, 5>;
și pentru metode:
template class Vector<int, 5>::Vector(int, int)

template int compara<int, int>(int, int)

2008 – 2018 © Catalin Boja 194


CLASE TEMPLATE – SPECIALIZĂRI

• definesc situații concrete in care metodele, funcțiile, clasele


se comporta diferit fata de situația generala
• au prioritate asupra abordării generale
• se aplica de obicei unor metode:
tip_returnat nume_clasa<tipc>::nume_metoda (lista parametrii) {
…}
• pot fi specializate clase template intregi:
template<> nume_clasa<tipc> { … }

2008 – 2018 © Catalin Boja 195


CLASE TEMPLATE

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> {…}

2008 – 2018 © Catalin Boja 196


CLASE TEMPLATE

• compunere de clase template prin


includere
• compunere de clase template prin
parametrizare cu alta clasa
template.
2008 – 2018 © Catalin Boja 197
STL – STANDARD TEMPLATE LIBRARY

• reprezintă o librărie de clase template standard


(standard template library)
• acoperă principalele structuri de date: vector, lista,
stiva, coada, tabela de dispersie (hash-table);
• pot fi utilizate fără alte modificări pentru tipuri
fundamentale sau definite de programator.

2008 – 2018 © Catalin Boja 198


STL – STANDARD TEMPLATE LIBRARY

CONTAINERE

ITERATORI ALGORITMI

2008 – 2018 © Catalin Boja 199


STL – CONTAINERE

• un obiect ce stochează alte obiecte si are


metode pentru a le accesa;
• tipuri (funcție de ordine si acces):
• forward
• reversible
• random access
• tipuri (funcție de aranjare):
• sequences
• associative containers
• container adaptors
2008 – 2018 © Catalin Boja 200
STL – CONTAINERE

0 1 2 3 4
“Piata Victoriei” “Calea Dorobanti” “Piata Victoriei” “Piata Romana” “Calea Dorobanti”

Parcurs agent vanzari: Lista magazine (cu duplicate) List

“Piata Victoriei” “Piata Romana”

“Calea Dorobanti” Set


Zona agent vanzari: Lista locatii (FARA duplicate)
100 … 145 … 200 Hash codes
Map
“Coca Cola” “Pepsi” “Mirinda” Nume produs
Lista produse vandute – dupa nume

2008 – 2018 © Catalin Boja 201


STL – CONTAINERE

• 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

2008 – 2018 © Catalin Boja 202


STL – ITERATORI

• forma generalizata a pointerilor;


• utilizați pentru a itera prin elementele containerelor
• interfață intre containere si algoritmi
• iteratori predefiniți:
• ostream_iterator;
• istream_iterator;
• reverse_iterator;
• insert_iterator;
2008 – 2018 © Catalin Boja 203
STL – ALGORITMI

• funcții generice independente de tipul containerului;


• utilizate pentru a prelucra elementele containerelor
• folosesc iteratori pentru acces la elemente
• funcții importante:
• copy;
• for_each;
• sort;
• find;
• transform

2008 – 2018 © Catalin Boja 204


RTTI

• Run-Time Type Identification


• mecanism pentru a determina la Run-
time tipul obiectului gestionat printr-un
pointer la baza
• are sens in contextul unei ierarhii de
clase + up-casting + funcții virtuale
2008 – 2018 © Catalin Boja 205
RTTI

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;

2008 – 2018 © Catalin Boja 206


RTTI

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

using namespace ComponenteGrafice;

pModel = new Dreptunghi();

if(dynamic_cast<Dreptunghi*>(pModel))

cout << endl << "Continut de tip Dreptunghi !";

Dreptunghi oDreptunghi = *dynamic_cast<Dreptunghi*>(pModel);

oDreptunghi.Arie();

2008 – 2018 © Catalin Boja 208

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