You are on page 1of 34

Florin Brleanu

Vrei s nvei C++, Java sau C#?


Trebuie mai nti s tii...

Programare orientat pe obiecte


pentru nceptori
6 lucrri practice n C++

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Cuprins:
1. Clase i obiecte
2. Constructori i destructori
3. ncapsulare i compunere
4. Suprascrierea metodelor i operatorilor
5. Motenire
6. Polimorfism

3
10
14
19
23
28

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Lucrarea nr. 1

Clase si obiecte
1. Scopul lucrarii
Lucrarea isi propune sa faca o introducere in programarea orientata pe
obiecte. Vor fi tratate in special conceptele esentiale de clasa si obiect. Dupa
efectuarea lucrarii vei cunoaste prin ce difera programarea orientata pe obiecte de
programarea clasica, procedurala, si vei sti sa declari clase si sa defineasca obiecte
din clasele respective.

2. Notiuni teoretice
Trebuie punctat inca de la inceput faptul ca se poate programa si fara a folosi
conceptele pe care le introduce programarea orientata pe obiecte. Orice program
realizat cu obiecte ar putea fi facut si folosind programarea clasica (procedurala).
Caci programarea orientata pe obiecte e doar un mod de a organiza programele, si
nu e in mod fundamental diferita de programarea procedurala.
Conceptul fundamental din programarea orientata pe obiecte (POO) il
constituie clasa. O clasa este in esenta o structura ce poate contine pe langa
variabile, functii. Deci o clasa este o structura ce grupeaza laolalta datele si actiunile
legate de un anumit tip de obiecte. Practic, ca si structura (struct, in limbajul C),
clasa (class, in limbajul C++) defineste un nou tip de date.
Folosind acest nou tip de date se pot defini, bineinteles, variabile -- care
poarta numele de obiecte. Accesarea membrilor unei clase se face, ca si in cazul
structurii, folosind operatorul . dupa un obiect apartinand clasei respective.
Variabilele sau obiectele continute intr-o clasa poarta numele de date membru
(sau campuri), iar functiile continute intr-o clasa poarta numele de functii membru
(sau metode). Atat campurile, cat si metodele, pot sa fie sau nu accesibile din
exteriorul clasei. Specificarea membrilor accesibili din afara ai unei clase se face
folosind specificatorul de acces public, in vreme ce pentru membrii inaccesibili
trebuie folosit specificatorul private.
In mod implicit (deci in cazul in care nu se scrie niciun specificator de acces)
toti membrii clasei sunt inaccesibili (ceea ce inseamna ca specificatorul de acces
private este implicit). Motivul pentru acest comportament este acela ca scopul
claselor este de a grupa laolalta (asa cum am spus) toate datele si actiunile
necesare pentru a opera cu un anumit tip (sau clasa) de obiecte. Iar gruparea
aceasta se face in scopul simplificarii muncii programatorului prin divizarea aplicatiei
software in clase de obiecte care sunt bine separate unele de altele si pot comunica
intre ele doar in moduri bine stabilite (fara ca un obiect dintr-o clasa sa trebuiasca sa
3

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

cunoasca detalii interne legate de implementarea unui obiect dintr-o alta clasa).
Asadar, detaliile interne ale unei clase trebuie tinute secrete (private) fata de
utilizatorii clasei respective, lasand vizibile (public) doar acele actiuni la care trebuie
sa poata raspunde obiectele acelei clase in vederea operarii cu ele. Este o practica
buna, asadar, ca toate datele membre ale unei clase sa fie private, in vreme ce doar
o parte dintre metode sa fie public.
Sintaxa pentru definirea unei clase in limbajul C++ este urmatoarea:
class NumeClasa {
private:
// date
// (si, eventual, unele metode)

int nr;
public:
// metode publice
// (actiuni ce pot fi realizate de catre obiectele clasei, sau
asupra lor)

void Scrie(int val);


int Citeste();
};
void NumeClasa::Scrie(int val)
{
nr = val;
}
int NumeClasa::Citeste()
{
return nr;
}

Odata declarata o clasa, ea poate fi utilizata pentru a defini obiecte in mod


similar utilizarii unui tip de date deja existent:
NumeClasa numeObiect;
Crearea unui obiect apartinand unei clase mai poarta numele de instantiere a clasei
respective. Ulterior definirii lui, obiectul numeObiect poate fi folosit pentru a apela
metodele publice. De exemplu, i se poate seta valoarea interna scriind:
4

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

numeObiect.Scrie(7);
Trebuie mentionat ca incercarea de a accesa un camp sau o metoda ce au
fost declarate cu private genereaza o eroare la compilarea programului.

3. Desfasurarea lucrarii
Exemplele si exercitiile din aceasta lucrare vor fi realizate folosind mediul de
dezvoltare Microsoft Visual C++. La crearea proiectului se va alege tipul Win32
Console Application.
3.1. Exemplu
Se va realiza urmatorul exemplu ce isi propune sa arate comparativ realizarea
unui program simplu in programarea clasica si in programarea orientata pe obiecte.
Programul isi propune sa afiseze pe ecran (in mod text) o tabla de X&O.
Rezultatul dorit este de genul urmator:
+-+-+-+
| | |X|
+-+-+-+
| | | |
+-+-+-+
|X|O| |
+-+-+-+
In fiecare dintre cele 9 pozitii de pe tabla se va putea gasi una dintre urmatoarele 3
piese:
- nimic (spatiu)
- piesa X (X)
- piesa O (O).
3.1.1. Solutia clasica
Pentru fiecare pozitie de pe tabla vom folosi o valoare de tip numar intreg
(int), cu urmatoarea semnificatie:
0 (spatiu)
1 X
2 O.
Prin urmare, cel mai natural e sa folosim o matrice de 3x3 elemente de tip numar
intreg.

Florin Brleanu Programare orientat pe obiecte pentru nceptori

Programul va avea urmatoarea structura:


Defineste tabla: int t[3][3];
Pune piese pe tabla: e.g. t[0][0] = 0; t[0][2] = 1;
Afiseaza tabla: void AfiseazaTabla(int t[3][3]).
Codul sursa al programului e prezentat in contiuare:
#include <stdio.h>
#include <conio.h>
void AfiseazaTabla(int t[3][3])
{
int l;
int c;
for (l=0; l<3; l++)
{
printf(+-+-+-+\n);
for (c=0; c<3; c++)
{
printf(|);
if (t[l][c] == 0) printf( );
else if (t[l][c] == 1) printf(X);
else if (t[l][c] == 2) printf(O);
}
printf(|\n);
}
printf(+-+-+-+\n);
}
void main(void)
{
// Defineste tabla:
int t[3][3];
// Pune piese pe tabla:
t[0][0] = 0; t[0][1] = 0; t[0][2] = 1;
t[1][0] = 0; t[1][1] = 0; t[1][2] = 0;
t[2][0] = 1; t[2][1] = 2; t[2][2] = 0;
// Afiseaza tabla:
AfiseazaTabla(t);
getch(); // asteapta...
}
3.1.2. Solutia POO
6

http://igotopia.ro

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Daca ne uitam cu atentie peste structura programului (care contine, in esenta,


trei actiuni: (1) defineste tabla, (2) pune piesele pe tabla si (3) afiseaza tabla),
observam ca intregul program consta in manipularea obiectului tabla. Asa ca am
putea grupa laolalta datele si actiunile privind tabla de joc, construind clasa
TablaDeJoc:
class TablaDeJoc {
private:
int t[3][3];
public:
void Afiseaza();
void PunePiesa(int l, int c, int p);
};
void TablaDeJoc::Afiseaza()
{
int l;
int c;
for (l=0; l<3; l++)
{
printf(+-+-+-+\n);
for (c=0; c<3; c++)
{
printf(|);
if (t[l][c] == 0) printf( );
else if (t[l][c] == 1) printf(X);
else if (t[l][c] == 2) printf(O);
}
printf(|\n);
}
printf(+-+-+-+\n);
}
void TablaDeJoc::PunePiesa(int l, int c, int p)
{
t[l][c] = p;
}
Asa cum se vede, clasa TablaDeJoc contine ca date matricea t (ce va
memora continutul fiecarei pozitii de pe tabla), iar ca metode Afiseaza() si
PunePiesa(). Ulterior declararii structurii clasei am definit aceste metode la fel cum
am defini niste functii obisnuite, doar ca numele lor le-am precedat de numele clasei
(TablaDeJoc) si de operatorul :: (care specifica faptul ca ne referim la un
7

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

identificator definit in cadrul clasei respective).


Pentru a scrie un program rulabil este necesar sa adaugam functia main
(plus eventualele fisiere antet ce declara functii sau alte clase pe care le folosim):
#include <stdio.h>
#include <conio.h>
class TablaDeJoc {
...
};
// definirea metodelor clasei TablaDeJoc
void main(void)
{
TablaDeJoc tabla;
tabla.PunePiesa(0, 0, 0); tabla.PunePiesa(0, 1, 0); tabla.PunePiesa(0, 2, 1);
tabla.PunePiesa(1, 0, 0); tabla.PunePiesa(1, 1, 0); tabla.PunePiesa(1, 2, 0);
tabla.PunePiesa(2, 0, 1); tabla.PunePiesa(2, 1, 2); tabla.PunePiesa(2, 2, 0);
tabla.Afiseaza();
getch();
}

Comparand programul acesta cu cel prezentat anterior se poate observa un


plus de claritate si de transparenta privind detaliile interne ale tablei. Acum matricea t
nu mai este definita in program, si nici nu este accesibila din afara clasei
TablaDeJoc. De asemenea, nu este necesara transmiterea ei ca parametru
metodelor Afiseaza() si PunePiesa() (caci fiind membre ale clasei TablaDeJoc ele au
acces direct la toti membrii clasei (inclusiv la cei declarati private)).
Un alt avantaj il constituie faptul ca daca ulterior dorim sa utilizam o alta
structura de date (eventual pentru a optimiza memoria utilizata) pentru a memora
continutul pozitiilor de pe tabla, vom putea face acest lucru fara sa afectam in vreun
fel programele care folosesc obiecte de tipul clasei TablaDeJoc. Aceste programe
vor ramane neschimbate ca forma, iar o simpla recompilare a lor va fi suficienta
pentru ca ele sa beneficieze de plusurile aduse de noua versiune a clasei.
Bineinteles, insa, ca exista si unele dezavantaje ale solutiei POO fata de
solutia clasica. Este evident ca in cazul programului oferit aici ca exemplu solutia
POO implica mai multa munca de codare, programul total fiind putin mai lung. Partea
buna este, insa, aceea ca munca poate fi mai bine impartita intre programatori in
cazul solutiei POO (unii putand lucra la construirea claselor necesare programului,
iar altii la programul propriu-zis). Odata realizata si testata o clasa, ea devine o
entitate de sine statatoare ce inglobeaza tot ce ii este necesar pentru a putea oferi
functionalitatea dorita, iar utilizarea ei va fi foarte facila (necesitand doar instantierea
ei si apoi utilizarea membrilor publici pe care ii ofera). Cu alte cuvinte, o clasa este
8

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

ca o cutie neagra ce stie sa execute un numar limitat de actiuni ca raspuns la un set


finit de mesaje.
3.2. Exercitii
(1) Sa se scrie si sa se ruleze cele doua programe folosind Visual C++. Notati
observatiile.
(2) Sa se modifice ambele programe astfel incat tabla sa nu mai fie de 3x3 pozitii, ci
de 4x4. Ce observati?
(3) Sa se modifice ambele programe rezultate la punctul (2) astfel incat variabila t sa
nu mai fie denumita t, ci x. Ce observati?
(4) Sa se adauge in clasa TablaDeJoc o metoda numita CePiesa(), care sa
returneze piesa de pe o pozitie specificata prin intermediul parametrilor. Prin ce ar fi
diferit aceasta metoda daca ar fi fost implementata ca functie in varianta clasica, si
nu ca metoda intr-o clasa?
(5) Sa se foloseasca in program aceasta metoda astfel: la finalul programului sa se
citeasca de la tastatura doua numere (linia si coloana); apoi sa se afiseze pe ecran
ce contine tabla la pozitia specificata.
(6) Sa se separe codul sursa al programului de la punctul (5) in mai multa fisiere,
astfel incat clasa TablaDeJoc si functia main sa fie definite in fisiere diferite. La ce
este utila aceasta activitate?

Bibliografie
[1] Peter Muller. Introduction to Object-Oriented Programming using C++.
http://www.tiem.utk.edu/~gross/c++man/
[2] Object-Oriented Programming in C++.
http://www.ntu.edu.sg/home/ehchua/programming/cpp/cp3_OOP.html
[3] http://www.cplusplus.com/doc/tutorial/classes/

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Lucrarea nr. 2

Constructori si destructori
1. Scopul lucrarii
In aceasta lucrare vei invata ce sunt constructorii si destructorii pentru o
clasa, la ce sunt utili si cum poti fi declarati si folositi in programe.

2. Notiuni teoretice
Constructorii si destructorii claselor sunt metode speciale ce se apeleaza in
mod automat:
- la crearea unui obiect constructorul
- la distrugerea unui obiect destructorul.
Pentru a intelege mai bine rolul si utilizarea constructorilor a a destructorilor,
este necesar sa revenim la modul cum sunt construite si distruse variabilele
obisnuite (care nu sunt obiecte).
O variabila normala (care nu e pointer) este creata in momentul definirii ei in
program, si este distrusa la iesirea din blocul ({...}) in care a fost definita:
{

int x; // creare obiect x


...
} // distrugere obiect x
Pe de alta parte, o variabila (sau spatiu de memorie) alocata prin intermediul
unui pointer (folosind operatorul new in C++) continua sa existe pana in momentul in
care este distrusa prin utilizarea operatorului delete (in C++):
int *px;
px = new int; // creare obiect (*px)

delete px; // distrugere obiect (*px)


Constructorul (sau constructorii) si destructorul unei clase se definesc ca
metode ce au acelasi nume ca al clasei (cu exceptia faptului ca destructorul mai are
o ~ imediat inaintea numelui) si nu returneaza nimic (nici macar void):
class NumeClasa {
10

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

private:

public:
NumeClasa(); // constructor fara parametri
NumeClasa(int parametru); // constructor un parametru

~NumeClasa(); // destructor
...
};
NumeClasa::NumeClasa()
{
...
}
NumeClasa::NumeClasa(int parametru)
{

}
NumeClasa::~NumeClasa()
{
...
}
...
Pentru a vedea mai clar utilitatea constructorului si a destructorului ne putem
gandi ca exemplu sugestiv la un obiect de tip MeniuContextual (care apare atunci
cand utilizatorul face click dreapta pe diverse elemente din interfata grafica a unei
aplicatii). Meniul care apare pe ecran (ca si functionalitatea aferenta lui) poate fi
diferit in functie de elementul din interfata pe care s-a facut click dreapta. Cum nu e
optim sa ocupam in permanenta memoria sistemului cu toate meniurile contextuale
posibile, le putem construi si distruge dinamic (cu operatorii new si delete). Astfel, in
constructor putem face (pe langa initializarile datelor interne) afisarea meniului pe
ecran, iar in destructor putem face stergerea lui de pe ecran.

3. Desfasurarea lucrarii
Exemplele si exercitiile din aceasta lucrare vor fi realizate folosind mediul de
dezvoltare Microsoft Visual C++. La crearea proiectului se va alege tipul Win32
Console Application.
3.1. Exemplu
11

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Pentru a ilustra modul in care se definesc si se folosesc constructorii pentru o clasa


vom relua exemplul discutat in lucrarea trecuta (clasa TablaDeJoc). Ii vom adauga
un constructor si un destructor astfel:
#include <stdio.h>
class TablaDeJoc {
private:
int t[3][3];
// camp
public:
TablaDeJoc();
// constructor implicit (i.e. fara parametri)
~TablaDeJoc();
// destructor
void Afiseaza();
// metoda
void PunePiesa(int l, int c, int p); // metoda
};
TablaDeJoc::TablaDeJoc()
{
int l, c;
for (l=0; l<=2; l++)
for (c=0; c<=2; c++)
t[l][c] = 0;
}
TablaDeJoc::~TablaDeJoc()
{
printf(Bye! :-)\n);
}
...

Constructorul TablaDeJoc::TablaDeJoc() se va apela in program automat in


momentul instantierii clasei TablaDeJoc (deci atunci cand definim obiectul tabla ( a
se revedea programul din lucrarea trecuta)):
TablaDeJoc tabla;
Desi o clasa poata avea un singur destructor, ea poate avea mai multi
constructori. Diferentierea intre ei compilatorul o va face (la fel ca in cazul metodelor
si al functiilor obisnuite) prin intermediul numarului si tipului parametrilor. Sa vedem,
de exemplu, cum am defini un constructor pentru clasa TablaDeJoc care in loc sa
initializeze elementele tablei cu valoarea 0, sa le initializeze cu o valoare primita ca
parametru:
TablaDeJoc::TablaDeJoc(int p)
12

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

{
int l, c;
for (l=0; l<=2; l++)
for (c=0; c<=2; c++)
t[l][c] = p;
}
Pentru a apela acest constructor va trebui ca in program sa modificam putin sintaxa
pentru instantierea clasei, construind obiectul tabla astfel:
TablaDeJoc tabla(1); // elementele tablei vor fi toate X
3.2. Exercitii
(1) In programul din lucrarea trecuta sa se apeleze tabla.Afiseaza() imediat dupa
instantierea clasei TablaDeJoc. Ce apare pe ecran?
(2) Sa se adauge constructorul implicit si sa se repete pasul anterior. Ce s-a
modificat?
(3) Sa se implementeze si constructorul cu parametru discutat anterior si sa se
testeze in program.
(4) Sa se adauge si destructorul clasei TablaDeJoc si sa se scrie un program de test
care sa ilustreze apelarea lui.

Bibliografie
[1] Constructors and destructors in C++.
http://www.cprogramming.com/tutorial/constructor_destructor_ordering.html
[2] Overview of contructors and destructors (C++ only).
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.i
bm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr374.htm
[3] http://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm

13

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Lucrarea nr. 3

Incapsulare si compunere
1. Scopul lucrarii
Scopul acestei lucrari il constituie intelegerea a doua concepe foarte
importante pe care este construita ideea programarii orientate pe obiecte. Voi
discuta si ilustra incapsularea si compunerea claselor.

2. Notiuni teoretice
Incapsularea e un concept de baza in programarea orientata pe obiecte. Ea
consta in gruparea laolalta (cadrul unei clase) a tuturor informatiilor esentiale ce
definesc obiectele din acea clasa (si se realizeaza, asa cum am arata in lucrarile
trecute, prin intermediul compurilor, metodelor si specificatorilor de acces).
Conceptul de incapsulare e legat si de ascunderea detaliilor interne ale unei
clase si lasarea vizibile doar a acelor detalii care sunt absolut necesare pentru
operarea cu acea clasa. Pentru a lasa posibilitatea modificarii ulterioare a structurii
interne a unei clase (in vederea optimizari sau a extinderii functionalitatii, de
exemplu), e necesar ca datele interne ale clasei sa fie invizibile (private), operarea
cu ele facandu-se prin intermediul unor metode vizibile (public):
class NumeClasa {
private:
int data;
public:

int CitesteData();
void ScrieData(int data);
};

int NumeClasa::CitesteData()
{
return data;
}
void NumeClasa::ScrieData(int data)
{
this->data = data;
14

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

}
A se remarca faptul ca in metoda ScrieData() oferita ca exemplu aici am
folosit pentru parametrul metodei acelasi nume cu al campului data din cadrul clasei
NumeClasa. Pentru ca compilatorul sa poata evita aceasta confuzie am folosit
sintaxa this->data, care acceseaza campul data al clasei NumeClasa prin
intermediul pointerului implicit this (care este un cuvant cheie in C++ si reprezinta un
pointer catre obiectul curent pentru care se apeleaza metoda). (Reamintesc faptul ca
operatorul -> are rolul de a dereferentia o zona de memorie referita printr-un
pointer si de a accesa apoi un camp din cadrul structurii continute acolo. Prin
urmare, this->data este echivalent cu (*this).data.)
Compunerea este un alt concept de baza in programarea orientata pe
obiecte. Ea se refera la faptul ca un obiect poate avea in compozitia sa (adica in
cadrul datelor membre) alte obiecte (de diferite tipuri). Aces mod de a construi
programe modeleaza aspecte din lumea reala, in care obiectele pot fi construite din
imbinarea mai multor alte obiecte mai mici.

3. Desfasurarea lucrarii
Exemplele si exercitiile din aceasta lucrare vor fi realizate folosind mediul de
dezvoltare Microsoft Visual C++. La crearea proiectului se va alege tipul Win32
Console Application.
3.1. Exemplu
3.1.1. Incapsulare
Un exemplu de incapsulare am vazut in lucrarile trecute. Este vorba de clasa
TablaDeJoc, ce incapsuleaza date si actiuni privitoare la o tabla de X&O.
Vom studia aici un alt exemplu: o clasa ce incapsuleaza date si actiuni
aferente operarii cu un numar complex.
Reamintesc faptul ca un numar complex este un numar de forma:
z = re + i* im
(Valorile re si im sunt numere reale, re fiind partea reala si im partea imaginara, iar i
este unitatea pe axa valorilor imaginare (fiind egal cu radacina patrata din (-1)).)
Prin urmare, pentru a putea opera cu un numar complex trebuie sa memoram doua
variabile -- partea imaginara si partea reala. In ceea ce priveste actiunile pe care sa
le putem face cu el, ne putem gandi la:
- accesarea partii reale si a partii imaginare (scriere/citire valori)
15

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

- calculul modulului
- calculul unghiului
- adunarea cu un alt numar complex
- inmultirea cu un alt numar complex
- etc.
Prezint in continuare o parte din definirea clasei NrComplex:
#include <math.h>
class NrComplex {
private:
double re;
// partea reala
double im; // partea imaginara
public:
// constructori:
NrComplex(); // constructor implicit
NrComplex(double re, double im); // constructor
// metode de acces:
double CitesteRe();
void ScrieRe(double re);
double CitestetIm();
voidScrieIm(double im);
// metode utilitare:
double Modul();
double Unghi();
void Aduna(NrComplex c);
void Inmulteste(NrComplex c);
...
};
NrComplex::NrComplex()
{
re = 0;
im = 0;
}
NrComplex::NrComplex(double re, double im)
{
this->re = re;
this->im = im;
}
double NrComplex::CitesteRe()
16

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

{
return re;
}
double NrComplex::ScrieRe(double re)
{
this->re = re;
}

double NrComplex::Modul()
{
return sqrt(re*re+im*im);
}

void NrComplex::Aduna(NrComplex c)
{
re += c.re;
im += c.im;
}

A se observa ca in metoda Aduna() am accesat campurile re si im ale


obiectului c (de tip NrComplex) primit ca parametru direct (folosind operatorul ., si
nu metodele de citire CitesteRe() si CitesteIm()). In mod normal acest lucru
genereaza o eroare de compilare (caci campurile re si im au fost definite ca fiind
private in clasa NrComplex). Totusi, cum metoda Aduna() face parte din clasa
NrComplex, ea are acces la elementele te tip private ale clasei (chiar daca acestea
apartin altei instante a clasei -- in cazul acesta fiind vorba de obiectul c).
3.1.2. Compunere
Un obiect de tip JocDeXsiO poate avea in compozitia sa obiecte de tip
TablaDeJoc (de care am discutat in lucrarile trecute) si de tip Jucator. Un exemplu in
acest sens este ilustrat in continuare:
class JocDeXsiO {
private:
TablaDeJoc tabla;
Jucator juc1;
17

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Jucatorjuc2;
public:
JocDeXsiO();
void Initializeaza();
void Joaca();
int RezultatJoc();
};
3.2. Exercitii
(1) Sa se implementeza clasa NrComplex si sa se scrie un program de test.
(2) Sa se implementeze clasa Jucator:
class Jucator {
private:
int tip; // 1 X; 2 O
public:
Jucator();
void StabilestePiese(int tip);
Piesa CitesteMutare();
// citeste de la tastatura mutarea
//
ca numar de la 1 la 9
};
Piesa reprezinta o structura definita dupa cum urmeaza:
struct Piesa {
int l;
int c;
int tip;
};
Sa se scrie un program de test pentru clasa Jucator.
(3) Sa se implementeze clasa JocDeXsiO si sa se scrie un program de test.

Bibliografie
[1] Objects and Encapsulation. http://sfb649.wiwi.hu-berlin.de/fedc_homepage/
xplore/ebooks/html/csa/node110.html

18

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Lucrarea nr. 4

Suprascrierea metodelor si operatorilor


1. Scopul lucrarii
Lucrarea aceasta are ca scop intelegerea rolului si utilizarii notiunii de
suprascriere a metodelor. De asemenea, se va studia modul in care operatorii
standard ai limbajului C++ pot fi facuti sa poata opera direct cu obiecte de diverse
clase.

2. Notiuni teoretice
Suprascrierea se refera in general la utilizarea aceluiasi nume pentru mai
multe functii, dar cu liste de parametri diferite. Compilatorul va putea face diferenta
intre acele functii pe baza parametrilor pe care ii folosim la apelul functiei in program.
Diferentierea intre listele de parametri se face atat dupa numarul parametrilor, cat si
dupa tipul lor. De exemplu, functiile
void f();
void f(int x);
void f(double x);
void f(int x, int y);
au toate acelasi nume, dar liste de parametri diferite -- deci nu va exista ambiguitate
si compilatorul va sti pe care dintre cele patru functii am apelat-o.
Deja am aratat intr-o lucrare anterioara un exemplu de suprascriere, si anume
suprascrierea constructorilor (o clasa putand avea atat constructor implicit, cat si
constructori cu parametri). Orice alta metoda poate fi suprascrisa in mod similar.
Un caz si mai interesant de suprascriere il constituie suprascrierea
operatorilor. Aceasta inseamna ca putem defini comportamentul operatorilor
standard ai limbajului C++ (operatori ca +, -, *, /, etc.) pentru ca acestia sa
poata opera cu obiecte din clase nou construite. De exemplu, putem face ca
operatorii aritmetici uzuali sa poata opera direct cu numere complexe (deci cu
instante ale clasei NrComplex definita intr-o lucrare anterioara).
Cu alte cuvinte, vom putea scrie in programe instructiuni de genul urmator:
NrComplex c1(2, -3);
NrComplex c2(1, 2);
NrComplex c3;
c3 = c1+c2; // = 3 - i

19

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Sintaxa pentru a suprascrie un operator este similara sintaxei utilizate pentru


definirea unei functii, cu mentiunea ca in loc de numele functiei se va scrie operator
urmat de operatorul care se doreste a fi redefinit. De exemplu, pentru suprascrierea
operatorului + de catre clasa NrComplex va trebui sa introducem in cadrul acesteia
urmatoarea metoda publica:
NrComplex operator+ (NrComplex c);
O alta varianta de a redefini functionarea operatorului + astfel incat sa poata
opera cu obiecte de tip NrComplex consta in a declara functia operator+ ca fiind
functie prietena (friend) a clasei NrComplex. Acest lucru se poate face scriind in
clasa NrComplex:
friend NrComplex operator+ (NrComplex c1, NrComplex c2);
si are rolul de a permite ca in corpul functiei operator+ (pe care il vom defini,
bineinteles, in afara corpului clasei NrComplex) sa putem accesa membrii privati re
si im ai obiectelor c1 si c2.

3. Desfasurarea lucrarii
Exemplele si exercitiile din aceasta lucrare vor fi realizate folosind mediul de
dezvoltare Microsoft Visual C++. La crearea proiectului se va alege tipul Win32
Console Application.
3.1. Exemplu
3.1.1. Suprascrierea metodelor
Un exemplu de suprascriere a metodelor in cadrul unei clase este ilustrat in
continuare, folosind drept cobai o clasa al carei scop este acela de a afisa pe ecran
numere de diverse tipuri:
class AfisorDeNumere {
public:
void Afiseaza(char x);
void Afiseaza(int x);
void Afiseaza(long x);
void Afiseaza(float x);
void Afiseaza(double x);
};
void AfisorDeNumere::Afiseaza(char x)
20

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

{
printf(%d, x);
}
...
void AfisorDeNumere::Afiseaza(float x)
{
printf(%f, x);
}

3.1.2. Suprascrierea operatorilor


Prezint in continuare modalitatea de redefinire a operatorilor + si * pentru a
putea opera cu obiecte de tip NrComplex:
class NrComplex {

public:
NrComplex operator+ (NrComplex c);
NrComplex operator* (NrComplex c);
};

NrComplex NrComplex::operator+ (NrComplex c)


{
NrComplex rez(this->re, this->im);
rez.re += c.re;
rez.im += c.im;
return rez;
}
NrComplex NrComplex::operator* (NrComplex c)
{
NrComplex rez(this->re, this->im);
rez.re *= c.re;
rez.re -= rez.im * c.im;
rez.im *= c.re;
rez.im + = rez.re * c.im;
return rez;
}
21

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

In continuare e ilustrata modalitatea de redefinire a operatorului + folosind o functie


prietena:
class NrComplex {

public:
friend NrComplex operator+ (NrComplex c1, NrComplex c2);
};
NrComplex operator+ (NrComplex c1, NrComplex c2);
{
NrComplex rez;
rez.re = c1.re + c2.re;
rez.im = c1.im + c2.im;
return rez;
}
3.2. Exercitii
(1) Sa se implementeze clasa AfisorDeNumere si sa se scrie un program de test
pentru ea.
(2) Sa se scrie cate un program de test pentru fiecare dintre cele doua metode de
suprascriere a operatorilor + si * prezentate (pentru clasa NrComplex).
(3) Dupa modelul clasei NrComplex, sa se scrie clasa Vector3D. (Sa se
implementeze si metodele ProdusScalar() si ProdusVectorial().)

Bibliografie
[1] C++ Operator Overloading Guidelines. http://courses.cms.caltech.edu/cs11/
material/cpp/donnie/cpp-ops.html
[2] Operator Overloading in C++. http://courses.cms.caltech.edu/cs11/material/
cpp/donnie/cpp-ops.html

22

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Lucrarea nr. 5

Mostenire
1. Scopul lucrarii
Scopul lucrarii de fata il constituie intelegerea modului in care clasele pot fi
reutilizate si extinse prin folosirea mostenirii.

2. Notiuni teoretice
Clasele pot fi extinse prin combinarea lor (asa cum am aratat in lucrarea referitoare
la compunerea claselor), dar si prin mostenire. Mostenirea in programarea orientata
pe obiecte este operatia prin care dintr-o clasa de baza se obtine o clasa derivata.
Clasa derivata extinde functionalitatea clasei de baza, specializand-o. Clasa de baza
este mai simpla, mai generica, mai abstracta, in vreme ce clasa derivata este mai
complexa, mai specifica, mai concreta.
Prin mostenire toate elementele clasei de baza se regasesc in clasa derivata, iar la
acestea se pot adauga unele noi si se pot modifica comportamente existente.
Pentru a intelege ideea de mostenire, ne putem gandi la clasele de forme
geometrice cele mai cunoscute. Astfel, daca avem o clasa de baza numita, de
exemplu, FormaGeometrica, putem deriva din ea clase ca Triunghi, Patrulater si
Elipsa. (Si zicem ca aceste clase mostenesc clasa FormaGeometrica). De
asemenea, putem avea si clase ca Trapez si Paralelogram, ce mostenesc clasa
Patrulater. In plus, mai putem avea si alte clase, rezultand o ierarhie arborescenta
de genul urmator:
FormaGeometrica
Triunghi
Dreptunghic
Isoscel
Echilateral
Patrulater
Trapez
Paralelogram
Dreptunghi
Patrat
Elipsa
Cerc

Chiar daca poate intr-un program nu s-ar justifica decat in rare cazuri
23

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

construirea unei asemenea ierarhii de clase derivate unele din altele, ea ilustreaza
bine la nivel conceptual in ce consta mostenirea claselor. De exemplu, in arborele de
mai sus vedem ca clasa Patrat mosteneste clasa Dreptunghi, care la randul ei
mosteneste clasa Paralelogram, care la randul ei mosteneste clasa Patrulater, care
la randul ei mosteneste clasa FormaGeometrica. Este evident ca orice patrat este un
dreptunghi, iar orice dreptunghi este un paralelogram, iar orice paralelogram este un
patrulater, iar orice patrulater este o forma geometrica.
In general, atunci cand zicem ca orice obiect de tip B este si un obiect de tip A
inseamna ca B are aceleasi tip de caracteristici ca si A, plus unele detalii. Atfel spus,
clasa B mosteneste clasa A (sau, echivalent, clasa B este derivata din clasa A (care
este, deci, clasa de baza pentru B)).
Montenirea se realizeaza folosind o constructie C++ de genul urmator:
class B : public A {
...
};
Tot ce continea clasa A va contine si clasa B, la care se vor adauga noile
campuri sau metode pe care le scriem in corpul clasei. In interiorul metodelor
adaugate in clasa B (in plus fata de cele importate din clasa A, bineinteles) vom
putea avea acces la membrii declarati ca fiind public sau protected din clasa A.
Specificatorul de acces protected se utilizeaza doar in contextul mostenirii claselor si
are rolul de a face ca respectivele campuri sa nu fie accesibile din exteriorul clasei
(ca si cum ar fi fost definite cu private), dar sa fie accesibile din interiorul claselor
derivate (caci toti membrii definiti ca fiind private in clasa de baza sunt inaccesibili
direct din interiorul noilor metode ale claselor derivate).
Specificatorul de acces utilizat inaintea numelui clasei de baza in exemplul de
mai sus hotaraste modul in care specificatorii de acces ai membrilor clasei de baza
se vor transforma in clasa derivata. In loc de public puteam folosi acolo fie protected,
fie private, efectele fiind redate in continuare:
Specificator mostenire:

In clasa de baza:

In clasa derivata:

public

public
protected
public
protected
public
protected

public
protected
protected
protected
private
protected

protected
private

O alta problema de interes o constituie modul in care se vor initializa obiectele


din clasa derivata. In mod implicit constructorul clasei de derivate apeleaza automat
contructorul implicit al clasei de baza. Prin urmare, la construirea unui obiect
24

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

apartinand clasei B se vor face mai intai initializarile specifice obiectelor clasei A
(caci in fond orice obiect din clasa B este un obiect din clasa A), dupa care se vor
putea adauga in constructorul clasei B alte initializari ce sunt necesare.
Daca se doreste, insa, apelarea dintr-un constructor al clasei B nu a
constructorului implicit, ci a unui constructor cu parametri, se poate proceda in felul
urmator:
class A {

public:
A(int x);
...
};
class B : public A {

public:
B(int x);
...
};
B::B(int x) : A(x)
{
// (eventual) alte initializari
...
}
Se mai pune problema si cum pot fi diferentiati membrii suprascrisi in clasa
derivata. Sa zicem ca in clasa Dreptunghi avem metoda Arie(), iar in clasa derivata
Patrat o redefinim. Intrebarea care se pune este cum mai putem avea acces la
metoda Arie() care a fost mostenita din clasa Dreptunghi (caci prin suprascrierea
metodei cea veche nu se sterge, ci ambele metode raman disponibile). Urmatorul
cod arata modul in care se poate solutiona aceasta problema:
int Arie()
{
return Dreptunghi::Arie();
}

3. Desfasurarea lucrarii
Exemplele si exercitiile din aceasta lucrare vor fi realizate folosind mediul de
dezvoltare Microsoft Visual C++. La crearea proiectului se va alege tipul Win32
25

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Console Application.
3.1. Exemplu
Pe langa exemplul discutat in partea teoretica a lucrarii, sa consideram o alta
ierahie de clase derivate unele din altele:
abstract
Animal

Caine

CaineAzor

clasa de baza
- caracteristicile generale ale unui animal
clasa derivata din clasa Animal
(si clasa de baza pentru clasa CaineAzor)
- caracteristicile generale ale unui animal
- caracteristici specifice cainilor
clasa derivata din Caine
- caracteristicile de baza ale unui animal
- caracteristici specifice cainilor
- caracteristici specifice lui Azor

concret
Daca ar fi sa reprezentam ca multimi matematice aceste trei clase, am avea
ceva de genul urmator:
+---------------------------------------------------+
|+-----------------------------------+
Animal
|
| | +--------------------+
Caine |
|
| | |
CaineAzor
|
|
|
| | +--------------------+
|
|
| +----------------------------------+
|
+---------------------------------------------------+
Aceasta diagrama arata foarte clar ca orice caine Azor este un caine, iar orice
caine este un animal. Pe de alta parte, insa, trebuie sa avem in vedere faptul ca
dimensiunile acestor diagrame nu reflecta realitatea in ceea ce priveste continutul
celor trei clase. Ci dimpotriva: clasa Animal contine cele mai putine elemente, la care
se adauga alte cateva elemente in clasa Caine, care sunt uterior completate cu alte
cateva in clasa CaineAzor. (Termenul elemente din ultima afirmatie poate ca nu
este cel mai bine ales, caci poate duce cu gandul la elemente ale multimii. Nu este
vorba de asa ceva, ci de elemente descriptive ale respectivei clase de obiecte. Iar
aceasta proportionalitate inversa intre numarul de obiecte ale unei clase si numarul
de elemente necesare descrierii ei nu este greu de inteles daca ne gandim la cum
stau lucrurile in realitate: cu cat dorim sa descriem o clasa mai restransa de obiecte,
cu atat avem nevoie de mai multe cuvinte.)

26

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

3.2. Exercitii
(1) Sa se implementeze ierarhia de clase cu baza in FormaGeometrica. Pentru
fiecare clasa sa existe metoda Arie(). Sa se scrie si un program de test.
(2) Sa se implementeze si testeze urmatoarea ierarhie de clase:
Animal
Caine
Pisica
Fiecare dintre aceste clase va contine metoda Vorbeste() ce va afisa pe ecran un
mesaj corespunzator clasei de obiecte respective.

Bibliografie
[1] C++ Inheritance. http://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm
[2] Introduction to inheritance in C++. http://www.cs.bu.edu/teaching/cpp/
inheritance/intro/
[3] Inheritance. http://www.cppforschool.com/tutorial/inheritance.html

27

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Lucrarea nr. 6

Polimorfism
1. Scopul lucrarii
Lucrarea aceasta isi propune intelegerea a ce este, la ce este util si cum se
poate folosi polimorfismul in programarea orientata pe obiecte.

2. Notiuni teoretice
Termenul de polimorfism se refera la ceva ce poate avea mai multe forme. In
programarea orientata pe obiecte acest termen este intalnit in doua situatii. Prima
dintre ele este polimorfismul parametric, care este doar un alt nume pentru ceea ce
se intampla atunci cand suprascriem metode (asa cum am aratat intr-o lucrare
anterioara). Cea ce-a doua situatie se refera la polimorfismul propriu-zis, care face
obiectul lucrarii de fata.
Polimorfismul se refera la faptul ca un pointer catre o clasa de baza poate
primi ca valoare adresa unei clase derivate si ii poate apela versiunea redefinita a
unei metode care in clasa de baza a fost declarata folosind cuvantul cheie virtual.
Cu alte cuvinte, notiunea de polimorfism e utilizata in contextul mostenirii claselor si
al pointerilor catre obiecte.
Sa zicem ca avem o clasa de baza FormaGeometrica si doua clase derivate
din aceasta: Dreptunghi si Cerc. Fiecare dintre aceste metode contine metoda Arie()
(redefinita in fiecare dintre clasele derivate).
Daca avem un obiect de tip Dreptunghi si un obiect de tip Cerc, putem folosi
oricare dintre aceste obiecte in program acolo unde ar fi trebuit sa folosim obiecte de
tip FormaGeometrica. Problema este, insa, aceea ca daca dupa ce am facut asta
incercam sa le apelam o metoda redefinita, ea nu va fi disponibila (ci se va apelea
versiunea metodei mostenita de la clasa de baza).
Daca, insa, in clasa de baza FormaGeometrica definim metoda Arie() ca fiind
virtuala (folosind cuvantul virtual inaintea declararii antetului metodei), atunci daca
atribui unui obiect de tip pointer catre FormaGeometrica adresa unui obiect de tip
Cerc si apelez metoda Arie() folosind pointerul se va apela versiunea redefinita in
clasa Cerc a metodei Arie(). Aceasta ne permite sa facem functii care sa opereze cu
clase de obiecte generice conform unui comportament prestabilit, urmand ca detalii
si extensii sa poata fi adaugate ulterior fara a face modificari in structura
programului.
Pentru a intelege mai bine utilitatea polimorfismului, sa ne gandim la
urmatoarea aplicatie. Sa zicem ca avem o aplicatie de manipulare simpla a unei
28

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

imagini. Aceasta aplicatie contine o fereastra, un spatiu in care poate fi afisata o


imagine, un buton de incarcare a imaginii, un buton pentru marire constrast si un
buton pentru micsorare contrast.
+--------------------------------------------------------------------------------------------------+
|----------------------------------------------------------------------------------------------------|
|
|
|
+----------------------------+
|
|
|
Incarca
|
|
|
+----------------------------+
|
|
+----------------------------+
|
|
| Mareste contrast |
|
|
+----------------------------+
|
|
+----------------------------+
|
|
| Micsoreaza contrast |
|
|
+----------------------------+
|
|
|
+--------------------------------------------------------------------------------------------------+
Prin urmare, aplicatia va permite doar incarcarea unei imagini de pe disc si apoi
marirea sau micsorarea contrastului ei.
Exista, insa, mai multe tipuri de imagini, ca: imagini binare, imagini in nuante
de gri, imagini color, etc. Ceea ce inseamna ca fiecare pixel din imagine poate sa fie
fie o valoare binara, fie o valoare scalara, fie o valoare vectoriala, etc. Asta
inseamna ca in functie de tipul de imagine atat incarcarea si afisarea imaginii, cat si
manipularea contrastului ei pot presupune operatii foarte diferite.
Putem proiecta ca aplicatia sa functioneze generic, considerand un obiect de
tip Imagine care contine toate operatiile pe care le putem face cu o imagine,
indiferent de ce tip e ea:
clasa Imagine:
- Incarca(fisier)
- Afiseaza()
- MaresteContrast()
- MicsoreazaContrast.
Apoi putem introduce pe rand suport pentru diverse tipuri de imagini. Partea
interesanta consta in faptul ca nu va fi nevoie sa modificam programul deja scris.
Daca am proiectat programul astfel incat sa opereze corect cu obiecte de tip
Imagine, el va sti sa opereze bine si cu obiecte de tip ImagineColor, de exemplu.
Trebuie doar sa definesc clasa ImagineColor care sa mosteneasca clasa Imagine si
sa ii redefineasca cele patru metode publice.astfel incat noile metode sa opereze
corect cu imagini color.
29

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Un element cheie aici pentru ca lucrurile sa functioneaza asa cum am discutat


este, repet, utilizarea cuvantului cheie virtual la declararea celor patru metode in
clasa de baza Imagine. De asemenea, un alt element esential este acela ca
programul generic trebuie realizat de asa maniera incat sa efectueze manipularile
asupra imaginii prin intermediul unui pointer catre un obiect de tip Imagine (clasa de
baza). Urmatoarea schita de cod ilustreaza un exemplu:
class Imagine {
...
public:
virtual void Afiseaza();
};
...
class ImagineColor : public Imagine {
public:
void Afiseaza();
};
...
Imagine *pimg;
ImagineColor imgColor;
pimg = &imgColor;
p->Afiseaza(); // va apela metoda redefinita in clasa ImagineColor
Asadar, polimorfismul e util in special pentru a construi clase care sa opereze
cu obiecte generice, a caror functionare sa nu fie alterata de schimbarea tipului
efectiv al obiectului, atata timp cat el se incadreaza in clasa generica de obiecte
recunoscute.

3. Desfasurarea lucrarii
Exemplele si exercitiile din aceasta lucrare vor fi realizate folosind mediul de
dezvoltare Microsoft Visual C++. La crearea proiectului se va alege tipul Win32
Console Application.
3.1. Exemplu
Vom dezvolta in continuare si vom discuta exemplul cu ierharhia de clase
FormaGeometrica, Dreptunghi si Cerc. Codul sursa al celor trei clase impreuna cu
programul de test este prezentat in continuare:
#include <stdio.h>
30

Florin Brleanu Programare orientat pe obiecte pentru nceptori

#include <conio.h>
class FormaGeometrica {
public:
int Arie();
};
int FormaGeometrica::Arie()
{
return 0;
}
class Dreptunghi : public FormaGeometrica {
private:
int a, b;
public:
Dreptunghi();
Dreptunghi(int a, int b);
int Arie();
};
Dreptunghi::Dreptunghi()
{
a = 0;
b = 0;
}
Dreptunghi::Dreptunghi(int a, int b)
{
this->a = a;
this->b = b;
}
int Dreptunghi::Arie()
{
return a*b;
}
class Cerc : public FormaGeometrica {
private:
int r;
public:
Cerc();
Cerc(int r);
int Arie();
};
Cerc::Cerc()
{
31

http://igotopia.ro

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

return 0;
}
Cerc::Cerc(int r)
{
this->r = r;
}
int Cerc::Arie()
{
return 3.14*r*r;
}
int main(void)
{
FormaGeometrica *pf;
Dreptunghi d(20, 50);
Cerc c(30);
int arie;
pf = &d;
arie = pf->Arie();
printf(%d\n, arie); // 0 !!!
getch();
pf = &c;
arie = pf->Arie();
printf(%d\n, arie); // 0 !!!
getch();
return 0;
}
Ruland programul se va observa ca pe ecran ariile calculate apar ca fiind
zero. Motivul este acela ca pf->Arie() apeleaza FormaGeometrica::Arie() (caci pf
este de tip pointer catre un obiect de tip FormaGeometrica, iar atat Dreptunghi, cat si
Cerc, sunt tipuri de FormaGeometrica (fiind clase derivate din aceasta), ambele
continand, deci, cate o metoda (mostenita) FormaGeometrica::Arie()).
Pentru ca rezultatule programului sa fie cele asteptate trebuie sa activam
polimorfismul. Si putem face aceasta definind metoda Arie() ca virtuala in clasa
FormaGeometrica:
class FormaGeometrica {
public:
virtual int Arie();
};
32

Florin Brleanu Programare orientat pe obiecte pentru nceptori

http://igotopia.ro

Recompiland programul si rulandu-l vom vedea ca de asta data primul pf>Arie() returneaza aria dreptunghiului, in vreme ce cel de-al doilea returneaza aria
cercului. Acest lucru e posibil datorita legarii dinamice (adica pentru o metoda
definita ca virtuala compilatorul nu pune direct apelul catre ea, ci abia la rularea
programului se decide ce metoda va fi apelata, in functie de tipul (clasa) obiectului
catre care pointerul indica.)
3.2. Exercitii
(1) Sa se implementeze programul dat ca exemplu, atat fara virtual, cat si cu.
(2) Sa se scrie o functie generica ce calculeaza aria unei forme geometrice primite
ca parametru, ii citeste tipul si afiseaza aceste informatii pe ecran. Apoi sa se
realizeze un program de test care sa verifice aceasta functie trimitandu-i drept
parametri obiecte de diverse forme geometrice.
Idee:
void AfiseazaArie(FormaGeometrica *pf)
{
printf(Tip obiect: %s. Arie: %d.\n, pf->Tip(), pf->Arie());
}

Bibliografie
[1] Polymorphism. http://www.cplusplus.com/doc/tutorial/polymorphism/
[2] Introduction to polymorphism in C++. http://www.cs.bu.edu/teaching/cpp/
polymorphism/intro/
[3] Polymorphism in C++. http://www.tutorialspoint.com/cplusplus/
cpp_polymorphism.htm
[4] C++ Polymorphism and Abstract Base Class. http://www.codingunit.com/
cplusplus-tutorial-polymorphism-and-abstract-base-class

33

Florin Brleanu Programare orientat pe obiecte pentru nceptori

Atept ntrebrile tale pe Facebook la


https://www.facebook.com/florinmarianb
sau pe email la
florin@igotopia.ro

34

http://igotopia.ro

You might also like