Sunteți pe pagina 1din 12

CAPITOLUL 4

Creareaierarhiilorde clase
3
Creareaierarhiilorde clase
4
1.Mecanismulmostenirii2.Declarareaclaselorderivate3.Constructoriiclaselorderivate4.
Mostenireasimpla5. Mostenireamultipla6. Redefinireamembriloruneiclasede bazain
clasaderivata7. FunctiivirtualesipolimorfismCAP. 4
5
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
Mostenireaesteocaracteristicaalimbajelordeprogramareorientateobiect,carepermiterefo
losireacoduluisiextindereafunctionalitatiiclaselorexistente.Mecanismulmosteniriiper
mitecreareauneiierarhiideclasesitrecereadelaclaselegeneralelaceleparticulare.
6
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
Aceastaproprietatesemanifestaprinfaptulcadinoriceclasaputemderivaalteclase.Procesul
implicala�nceputdefinireaclaseidebazacarestabilestecalitatilecomunealetuturorobiect
elorcevorderivadinclasadebaza(clasaierarhicsuperioara).
Prinmostenire, un obiectpoatepreluaproprietatileobiectelordin clasade baza.
7
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
?Mostenireasimpla(unica):?Fiecareclasaaredoarosuperclasa?Structuraarbore
?Mostenireamultipla:?Oclasaaremaimultesuperclase?StructurareteaMostenireapoatefi:
8
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
Informatiacomunaapare�nclasadebaza,iarinformatiaspecifica-
�nclasaderivata.Clasaderivatareprezintaospecializareaclaseidebaza.Oriceclasaderivat
amostenestedatelemembrusimetodeleclaseidebaza,deciacesteanutrebuieredeclarateinclas
aderivata.
9
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
?C+
+:�ncapsularea�princontrolulaccesului,deoarecetoatedatelesifunctiilemembresuntcarac
terizateprintr-unniveldeacces(rezult�ndastfelomareflexibilitate).?niveldeacces?
private?protected?public?(friend)?Mostenire?private?protected?public
10
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
?private: membrii(date simetode) la care accesulesteprivate pot fi
accesatidoarprinmetodeleclasei(nivelde accesimplicit); ?protected: acestimembripot
fi accesatiprinfunctiilemembreale claseisifunctiilemembreale claseiderivate; ?
public: membrii la care accesul este public pot fi accesati din orice punct al
domeniului de existenta a clasei respective; ?friend: acestimembripot fi
accesatiprinfunctiilemembreale functieiprietenespecificate.
Nivelulde accesla membriiuneiclase
11
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
?Publica, unde �n clasa derivata nivelul de acces al membrilor este acelasi ca �n
clasa de baza; ?Privata, unde membrii protected si public din clasa baza devin
private �n clasa derivata. ?Protejata(la compilatoarelemainoi).
�nlimbajulC++, nivelulde accespoateprecizasitipulde mostenire
12
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
C�nd o clasa mostenestemembrii unei alte clase, membrii clasei de baza devinmembrii
ai clasei derivate.
Mostenireaprotejataesteintermediaraceleipublicesiceleiprivate.�ncazulmosteniriiprot
ejate,comparativcumostenireprivata,singuradiferentaestecamembriipubliciaiclaseideba
zadevinprotejati�ntimpulderivarilorulterioare.
13
CAP. 4
4.1. Mecanismulmostenirii
Creareaierarhiilorde clase
�n functie de modificatorii de acces la membrii clasei de baza, la membrii clasei
derivate si de tipul mostenirii, lucrurile se pot rezuma astfel
Asa cum se observa, �n toate cazurile:-elementele private ale clasei de baza ram�n
particulare acesteia si nu sunt accesibile claselor derivate; -cele protejate sunt
accesibile clasei derivate.
14
CAP. 4
4.2. MODUL DE DECLARARE A CLASELOR DERIVATE
Creareaierarhiilorde clase
Lamodulgeneral,ladeclarareauneiclasederivate,sespecificaolistaaclaselordebaza,prece
datedemodificatoruldeaccescareprecizeazatipulmostenirii.class<nume_cls_deriv>:<modi
ficator_de_acces><nume_clasa_de_baza> { //corpul clasei derivate -elemente
specifice clasei derivate };
15
CAP. 4
4.2. MODUL DE DECLARARE A CLASELOR DERIVATE
Creareaierarhiilorde clase
Exemplu:
Declararea clasei derivate angajat, cu clasa de baza persoana (mostenire simpla):
class persoana{ // corpul clasei de baza }; class angajat: protected
persoana{double salariu; };
16
CAP. 4
4.2. MODUL DE DECLARARE A CLASELOR DERIVATE
Creareaierarhiilorde clase
Exemplu:
Declararea clasei derivate interfata, cu clasele de baza fereastrasi
meniu(mostenire multipla): class fereastra{ //membriiclasei};class meniu{
//membriiclasei};class interfata: public fereastra, public meniu{ //membriiclasei};
17
CAP. 4
4.3. CONSTRUCTORII CLASELOR DERIVATE
Creareaierarhiilorde clase
Constructoriisidestructoriisuntfunctiimembrecare NUse mostenesc.
Lainstantiereaunuiobiectdinclasaderivataseapeleazamai�nt�iconstructoriiclaselordeba
za,�nordinea�ncareacestiaapar�nlistadedeclarareaclaseiderivate.Ladistrugereaobiecte
lor,seapeleaza�nt�idestructorulclaseiderivate,apoidestructoriiclaselordebaza.Transm
itereaargumenteloruneifunctiiconstructordinclasadebazasefacefolosindoformaextinsaad
eclaratieiconstructoruluiclaseiderivate,caretransmiteargumenteleunuisaumaimultorcon
structoridinclasadebaza.
18
CAP. 4
4.3. CONSTRUCTORII CLASELOR DERIVATE
Creareaierarhiilorde clase
�ngeneral,claseleutilizeazaconstructoridefinitideprogramator.�ncazul�ncareacestiali
psesc,compilatorulgenereazaautomatunconstructorimplicitpentruclasarespectiva.Acelas
ilucruse�nt�mplasi�ncazulconstructorilordecopiere.Lainstantiereaunuiobiectdinclasad
erivata,opartedinvalorileprimitecaparametrifolosesclainitializareadatelormembrualec
laselordebaza,iarrestulinitializeazadatelemembruspecificeclaseiderivate.
19
CAP. 4
4.3. CONSTRUCTORII CLASELOR DERIVATE
Creareaierarhiilorde clase
20
CAP. 4
4.4. MOSTENIREA SIMPLA
Creareaierarhiilorde clase
Exemplu:
Se implementreaza ierarhia de clase din figura: #include <iostream.h> class
baza{ private: inta; protected: double w; void seteaza_a(inta1) {a=a1;} void
seteaza_w(intw1) {w=w1;}
Pentruaevidentiaaspecteleprezentate,saconsideramurmatoareleexemple,�ncaremostenirea
estesimpla:
21
CAP. 4Creareaierarhiilorde clase
public: intc;baza(inta1, double w1, intc1) {a=a1; w=w1; c=c1;cout<<"Constructor
cls. baza\n";} ~baza() {cout<<"Destructor baza\n";} void arata() {cout<<a<<'
'<<w<<' '<<c<<'\n';} double calcul() {return a+w+c;} friend ostream&
operator<<(ostream&, constbaza&); }; 4.4. MOSTENIREA SIMPLA
22
CAP. 4Creareaierarhiilorde clase
class deriv1: public baza{ intb; public: deriv1 (inta1, double w1, intc1,
intb1):baza(a1, w1, c1) {b=b1; cout<<"Constructor deriv1\n";} ~deriv1()
{cout<<"Destructor deriv1\n";} double calcul() {return w+c+b;} // membrula
este�ncapsulat, nu poatefi folosit, fiindprivate // o alternativa pentru obtinerea
sumei tuturor datelor membre este: // double calcul(){return baza::calcul()+b;}
friend ostream&operator<<(ostream&, constderiv1 &); }; 4.4. MOSTENIREA SIMPLA
23
CAP. 4Creareaierarhiilorde clase
class deriv2: protected baza{ intb; public: deriv2(inta1, double w1, intc1,
intb1):baza(a1, w1, c1) {b=b1; cout<<"Constructor deriv2\n";} ~deriv2()
{cout<<"Destructor deriv2\n";} double calcul() {return w+c+b;} friend
ostream&operator<<(ostream&, constderiv2 &); }; 4.4. MOSTENIREA SIMPLA
24
CAP. 4Creareaierarhiilorde clase
intmain() { baza x(1, 1.23, 2); // Constructor cls. baza deriv1 y(2, 2.34, 3,
4); // Constructor cls. baza Constructor deriv1 deriv2 z(3, 3.45, 4, 5); //
Constructor cls. baza Constructor deriv2 deriv3 v(4, 5.67, 6, 7); //Constructor
cls. baza Constructor deriv3 cout<<"x="<<x<<'\n'<<"z="<<z<<'\n'<<"v="<<v<<'\n'; //
x=1 1.23 2 (x.a, x.w, x.c) // z=3.45 4 5 // v=5.67 6 7
cout<<"x.calcul()="<<x.calcul()<<'\n'; // x.calcul()=4.23
cout<<"y.calcul()="<<y.calcul()<<'\n'; // y.calcul()=9.34
cout<<"z.calcul()="<<z.calcul()<<'\n'; // z.calcul()=12.45
cout<<"v.calcul()="<<v.calcul()<<'\n'; // v.calcul()=18.67 cout<<"x.c="<<x.c<<'\n';
// x.c=2 cout<<"y.c="<<y.c<<'\n'; // y.c=3 /* Destructor deriv3 Destructor baza
ptr. v Destructor deriv2 Destructor baza ptr. z Destructor deriv1 Destructor baza
ptr. y Destructor bazaptrx */ } 4.4. MOSTENIREA SIMPLA
25
CAP. 4Creareaierarhiilorde clase
Observatii:
�n clasa de baza data membra aeste private, weste protectedsi ceste public. �n
clasa de baza, c�t si �n clasele derivate exista constructori care initializeaza
datele membru. Membrii privatedintr-o clasa de baza (clasa baza, �n cazul nostru)
pot fi folositi doar �n cadrul acesteia (de metodele sale), nusi �n clasele
derivate. Clasaderiv1: Membrii privati mosteniti din clasa baza sunt inaccesibili
(a exista, dar este �ncapsulat). Pentru a putea fi accesati, se folosesc metodele
clasei baza (metoda calcul). Deoarece �n clasa deriv1 exista o metoda cu acelasi
nume cu al unei metode din clasa de baza (redefinirea unei metode �n clasa
derivata), se foloseste operatorul de rezolutie. baza::calcul( )
sauy.baza::calcul( ) 4.4. MOSTENIREA SIMPLA
26
CAP. 4Creareaierarhiilorde clase
Clasaderiv2:Deoarecemostenireaesteprotejata,membriipublicisauprotejatidinclasabazad
evinprotejati�nclasaderiv2.Deaceea,daca�nfunctiamainam�ncercafolosirea:cout<<z.baza
::calcul(),metodacalculesteinaccesibila,eadevenindprotejata�nclasaderiv3.Clasaderiv
3:Deoarecemostenireaesteprivata,membriipublicsauprotecteddinclasabazaaudevenitpriva
ti�nclasaderiv3.Sepotfolositotimembriiclaseidebaza,cuexceptiacelorprivati(a).4.4.
MOSTENIREA SIMPLA
27
CAP. 4Creareaierarhiilorde clase
Laconstruireaunuiobiectdintr-
oclasaderivatadinclasabaza,seapeleazamai�nt�iconstructoruldinclasadebaza,apoiconstr
uctorulclaseiderivate.Astfel,unobiectydinclasaderiv2incorporeazaunobiectdejainitial
izatcuajutorulconstructoruluidinclasabaza.Dacapentruclasaderiv1defineamunconstructo
rdeforma:deriv1(inta1,doubleb1,intc1,intb1)
{a=a1;b=b1;c=c1;d=d1;}nueracorect,deoarececlasabazanuareconstructorifaraparametri,d
ecinuexistaconstructorimplicit,iardataaesteinaccesibila�nderiv1.Apelareaconstructor
uluiserealizeazaapel�ndexplicitconstructoruldinclasabaza.4.4. MOSTENIREA SIMPLA
28
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAO clasa poate sa mosteneasca mai multe clase de baza, ceea
ce �nseamna ca toti membrii claselor de baza vor fi mosteniti de catre clasa
derivata. �n aceasta situatie apare mecanismul mostenirii multiple.
29
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAExercitiu:Se implementeaza ierahia de clase din figura.
#include <iostream.h> class baza1{ protected: intx; public: baza1 (int xx) {x=xx;
cout<<"Constructor cls. baza1\n"; cout<<x<<'\n';} ~baza1() {cout<<"Destructor
baza1\n"; cout<<x<<'\n';} void aratax() {cout<<"x="<<x<<'\n';} };
30
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAclass baza2 { protected: inty; public: baza2 (int yy)
{y=yy; cout<<"Constructor baza2\n"<<y<<'\n';} ~baza2() {cout<<"Destructor
baza2\n";} voidaratay() {cout<<"y="<<y<<'\n';} }; class derivat: public baza1,
public baza2 { public: derivat(int xx, int yy):baza1(xx), baza2(yy)
{cout<<"Constructorderivat\n"; cout<<x<<' '<<y<<'\n';} ~derivat()
{cout<<"Destructorderivat\n"; cout<<x<<' '<<y<<'\n';} intarata() {cout<<x<<'
'<<y<<'\n';} void seteaza(intxx, intyy) {x=xx; y=yy;} };
31
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAintmain() {derivatobiect(7,8); /*Constructor cls. baza1 7
Constructor baza2 8 Constructor derivat7 8 */ obiect.arata(); // 7 8
obiect.seteaza(1,2);obiect.aratax(); // x=1 obiect.aratay(); // y=2 obiect.arata();
// 1 2 /* Destructor derivat1 2 Destructor baza2 2 Destructor baza1 1 */ }
32
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA
MULTIPLAAsacumilustreazaexemplul,ladeclarareaobiectuluiobiectdetipulderivats-
auapelatconstructoriiclaselordebaza(baza1sibaza2),�nordinea�ncareapar�ndeclarareacl
aseiderivate:mai�nt�iconstructorulclaseibaza1,�ncarexestedatamembruprotejata(accesi
biladinclasaderivat);apoiconstructorulclaseibaza2,�ncareyestedatamembruprotejata(ac
cesibiladinclasaderivat);apoiconstructorulclaseiderivatcarele�ncorporeazapeacestea�
ntr-unsingurobiect.Clasaderivatnuaredatemembre,cidoarmetode(figura).
Dupa iesirea din blocul �n care a fost declarata variabila obiect, se apeleaza
automat destructorii, �n ordine inversa apelarii constructorilor.
33
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAAmbiguit�ti�nmostenireamultipl��ntr-o mostenire multipla
este posibil ca o clasa sa fie mostenita indirectde mai multe ori, prin intermediul
unor clase care mostenesc, fiecare �n parte, clasa de baza. �n situatia aparitiei
unei astfel de �mosteniri repetata�, �n care o clasa ajunge sa mosteneasca de la
aceeasi clasa, pe drumuri diferite �n retea (vezi figura1, �n care clasa D
mosteneste de la aceeasi clasa A, pe drumurile A-B-D, A-C-D), limbajul C++ ofera
programatorului doua strategii: 1)clasa E poate avea doua copii ale lui A, una
pentru fiecare drum; 2)clasa D are o singura copie, iar A este clasa virtuala de
baza si pentru C si pentru B.
34
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAFie schema de mostenire prezentata �n figura1. La
declararea unui obiect din clasa D, membrii clasei A (int a) sunt mosteniti de
obiectul din clasa D �n dublu exemplar (figura2.).
35
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAclass A{ public: inta; //���. }; class B: public A{
/*����..*/ }; class C: public A{ /* ����������..*/ }; class D: public B, public C {
/* �����������*/ }; intmain() {D x; //declarare obiectx de tipD x.a= 2; //
eroareD::x esteambiguu; poatefi �nbazaA aclaseiB // sau�nbazaA aclaseiC }
36
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAEliminarea ambiguitatii aparute �n situatia prezentata se
poate realiza �n doua moduri:1.Prin pastrarea a doua copii ale lui A, una pentru
fiecare drum, specific�nd clasa de apartenenta: x.B::a = 2; // corect, a din B
x.B::a = 3; // corect, a din C 2.Prin crearea unei singure copii a clasei de baza
�n clasa derivata. Pentru aceasta este necesar ca acea clasa care ar putea produce
copii multiple prin mostenire indirecta (clasa A, �n exemplul de mai sus) sa fie
declarata clasa virtuala�n clasele care o introduc �n clasa cu mostenire multipa.
Clasa A va fi declaratavirtuala, pentru clasele derivate B si C.
37
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLAO clasa de baza virtuala este mostenita o singura data
(figura) si creeaza o singura copie �n clasele derivate, oferind astfel o
modalitate de �partajare� a membrilor sai de catre clasele derivate.
38
CAP. 4Creareaierarhiilorde clase
4.5. MOSTENIREA MULTIPLA
De exemplu: class A { public: intx; /* �������.*/ }; class B : virtual public A
{ /*��� */ }; class C : virtual public A { /*��������.*/ }; class D : public B,
public C { /* ��������. */ };
39
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATAAsa cum s-a observat
deja din exercitiile anterioare, membrii (fie date membru, fie metode) ai unei
clase de baza pot fi redefiniti �n clasele derivatedin aceasta. �n urmatorul
exemplu, datele membre x si y din clasa baza sunt redefinite �n clasaderivata,
deriv. Exemplul 1 (�n care se redefinesc datele membre ale clasei de baza �n clasa
derivata)
class baza{ protected: double x, y; public: baza(double xx=0, double yy=0) {x=xx;
y=yy;} };
40
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA�N CLASA DERIVATAclass deriv:public
baza{ protected: double x, y; public: deriv(double dx=0,double dy=0,double
bx=0,double by=0):baza(bx,by) {x=dx; // x -membru redefinit �n clasa derivata y=dy;
// y -membruredefinit�nclasaderivata} void arata() const; }; void deriv::arata()
const {cout<<"x dinclasade baza:"<<baza::x; cout<<"\ty din clasa de
baza:"<<baza::y<<'\n'; cout<<"x din clasa derivata:"<<x;
cout<<"\tydinclasaderivata:"<<y<<'\n'; } main() { /*�����.*/} �n metoda arata a
clasei deriv, pentru a face distinctie�ntre datele membru ale
clasei deriv si cele ale clasei baza, se foloseste operatorul de rezolutie.
41
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATA�n urmatorul
exemplu, metoda arataeste redefinita �n clasele B, C, D, iar clasa de baza A este
clasa virtuala pentru clasele derivate (cu scopul de crea o singura copie a
membrilor acesteia si a evita ambiguitatile, asa cum s-a discutat
anterior)Exemplul2:
#include <iostream.h> class A{ inta; public: A(intaa) {a=aa; cout<<"Constructor
A"<<a<<'\n';} ~A() {cout<<�Destructor A�;} void arata() {cout<<"A.a="<<a<<'\n';} };

42
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATAclass B: virtual
public A{ intb; public: B(intbb, intaa=0):A(aa) {b=bb;cout<<"Constructor
B"<<b<<'\n';} ~B() {cout<<�Destructor B�;} void arata() {cout<<"B.b="<<b<<'\n';} };
class C: virtual public A{ intc; public: C (intcc, intaa=0):A(aa) {c=cc;
cout<<"ConstructorC"<<c<<'\n';} ~C() {cout<<�Destructor C�;} void arata()
{cout<<"C.c="<<c<<'\n';} }; class D: public B, public C{ intd; public: D(intaa,
intbb, intcc, intdd):A(aa), B(bb), C(cc) {d=dd;cout<<"Constructor D"<<d<<'\n';}
~D() {cout<<�Destructor D�;} void arata() {cout<<"D.d="<<d<<'\n';} };
43
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATAintmain() {D
x(1,2,3,4); /* Constructor A1 Constructor B2 Constructor C3 Constructor D4 */
x.arata(); // apelul metodei arata din clasa D, pentru obiectul x D.d=4
x.B::arata(); // apelul metodei arata din clasa B B.b=2 x.C::arata(); // apelul
metodei arata din clasa C C.c=3 x.A::arata(); // apelul metodei arata din clasa A
A.a=1 /* Destructor D Destructor C Destructor B Destructor A */ A u(10); //
Constructor A 10 -ptr. obiectulu, de tipA B v1(9, 7);// Constructor A 9 Constructor
B 7 -ptr. obiectulv1, de tipB C v2(8,12);// Constructor A 8 Constructor C 12 -ptr.
obiectulv2, de tipC D w(31, 9, 14, 35);// Constructor A 31 Constructor B 9
Constructor C 14 // ConstructorD35 -ptr. obiectulw, de tipD
44
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATA// Se apeleaza
metoda arata, pentru obiectul curent u.arata(); // A.a=10 v1.arata(); // B.b=7
v2.arata(); // C.c=12 w.arata(); // D.d=35 /* Destructor D Destructor C Destructor
B Destructor A -ptr. obiectulw Destructor C Destructor A -ptr. obiectulv2
Destructor B Destructor A -ptr. obiectulv1 Destructor A -ptr. obectulu */ }
45
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATAAsa cum se observa
din exemplul 2, metoda arata din clasa de baza A a fost redefinita�n clasele
derivate B, C, D. �n plus, metoda are aceeasi semnatura(acelasi prototip) �n toate
clasele. Daca nu ar fi fost redefinita �n clasele derivate, metoda arata (publica)
din clasa de baza A ar fi fost mostenita de clasele derivate; redefinirea a fost
necesara pentru a putea vizualiza si datele membre proprii claselor derivate. �n
cazul de fata, identificarea metodei apelate se realizeaza chiar �n etapa
compilarii, datorita legaturii cu obiectul pentru care a fost apelata. De exemplu,
la apelul w.arata() se aplica metoda din clasa D (obiectul w e de tip D)
1
46
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATAConcluzion�nd,
identificarea unei metode din clasa de baza redefinite �n clasele derivate, se face
prin una din modalitatile: ?Prin legatura cu obiectul asupra caruia se aplica
metoda (vezi apelurile metodei arata pentru obiectele u, v1, v2, w); ?Prezenta
operatorului de rezolutie (de exemplu, daca pentru obiectul w se doreste apelarea
metodei arata din clasa B, apelul va avea forma: w.A::arata(); ).
/
47
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATARedefinirea unei
metode a unei clase de baza �ntr-o clasa derivata se numeste polimorfism. Un
pointer catre o clasa de baza poate primi ca valoare adresa unui obiect dintr-o
clasa derivata. �n aceasta situatie, �n cazul metodelor redefinite, se apeleaza
metoda din clasa pointerilor, si nu din clasa obiectului spre care pointeaza
pointerul.
48
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATAPentru
exemplificare, vom considera ierarhia de clase (A, B, C, D) ulterioara, si
programul de test: intmain() { A u(10), *PA; // Constructor A 10 B v1(9, 7),
*PB; // Constructor A 9 Constructor B 7 -ptr. v1 C v2(8,12), *PC; // Constructor A
8 Constructor C 12 -ptr. v2 D w(31, 9, 14, 35), *PD; // Constructor A 31
Constructor B 9 // Constructor C 14 Constructor D 35 PA=&u; PA->arata(); // Se
selecteaza metoda arata din clasa A A.a=10 PA=&v1; PA->arata(); // Se selecteaza
metoda arata din clasa A A.a=9 PB=&v1; PB->arata(); // Se selecteaza metoda arata
din clasa B B.b=7 PA=&w; PB=&w; PD=&w; u.arata(); // Apelul metodei arata ptr.
obiectul curent, clasa A A.a=31 PA->arata(); // Se selecteaza metoda arata din
clasa A A.a=31 PB->arata(); // Se selecteaza metoda arata din clasa B B.b=9 PD-
>arata(); // Se selecteaza metoda arata din clasa D D.d=35 }
49
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATAAsa cum se observa
din exemplu, pa, pb, pc si pd sunt pointeri de tipurile A, B, C, respectiv D: A
*pa;B*pb;C*pc;D*pd; �nurmaatribuiriipa=&v1; pointerulpa (de tip A)
vacontineadresaobiectuluiv1 (de tip B). Apelul metodei arataredefinita �n clasa
derivata B pa->arata(); va determina selectia metodei din clasa pointerului (A), si
nu a metodei din clasa obiectului a carui adresa o contine pointerul.
50
CAP. 4Creareaierarhiilorde clase
4.6. REDEFINIREA MEMBRILOR UNEI CLASE DE BAZA �N CLASA DERIVATA
�n toate cazurile prezentate anterior, identificarea metodei redefinite se
realizeaza �n faza de compilare.Este vorba de o legare intiala (timpurie), "early
binding", �n care toate informatiile necesare selectarii metodei sunt prezentate
din timp si pot fi utilizate din faza de compilare.
51
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMAsacums-
asubliniat,unpointerlaoclasadebazapoateprimicavaloareadresaunuiobiectdintr-
oclasaderivata.Saluamcaexemplusituatia�ncareav�nduntabloudepointerilaobiectedetipA,
putemlucracutablourideobiecteeterogene,cuelementedetipuridiferite(B,CsauD);decelema
imulteori,informatiileprivindtipulobiectuluilacarepointeazaunelementaltablouluisunt
disponibileabia�nmomentulexecutieiprogramului.�ncazulexemplificat,orezolvareaidenti
ficariimetodei�nmomentulexecutieiprogramuluioconstituiefunctiilevirtuale.
52
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMOfunctievirtualaesteofunctiecareestedeclaratadetipvirtual�nclasadebazasi
redefinita�ntr-oclasaderivata.Redefinireauneifunctiivirtuale�ntr-
oclasaderivatadomina(override)definitiafunctiei�nclasadebaza.Functiadeclaratavirtua
l�nclasadebazaactioneazacaodescrieregenericaprincaresedefinesteinterfatacomuna,iarf
unctiileredefinite�nclaselederivateprecizeazaactiunilespecificefiecareiclasederivat
e.
53
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMMecanismuldevirtualitateasiguraselectia(dominarea)functieiredefinite�ncl
asaderivatanumailaapelulindirectalfunctiei,printr-
unpointer1catreunobiect.Laapeluldirect(functiemembraapelatapentruunobiect2cuajutoru
loperatoruluideselectiedirecta(.),�leg�nd-
o�deobiect),functiilevirtualesecomportanormal,cafunctiiredefinite.Deoarecemecanismu
ldevirtualitatesemanifestanumai�ncazulapeluluifunctiilorprinintermediulpointerilors
evorprecizamai�nt�iaspecteleprivindconversiiledepointeri�ntreclaseledebazasiclasele
derivate.
54
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMConversiialepointerilor�ntreclaseledebazasiclasederivateConversiadintr-
unpointerlaoclasaderivata�npointerlaoclasadebazaaacesteiaesteimplicita,dacaderivare
aestedetippublicsinuexista
ambiguitati.Conversiadintr-
unpointerlaoclasadebaza�npointerlaoclasaderivatanuesteadmisaimplicit,�nsapoatefirea
lizataexplicit,prinoperatoruldeconversiecast.Rezultatuluneiastfeldeconversiieste�ns
anedeterminat,decelemaimulteoriprovoc�nderorideexecutie.
55
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMObservatii:
1.Referintelepotficonvertite�nmodasemanator:oreferintalaunobiectdintr-
oclasaderivatapoateficonvertitaimplicit�ntr-
oreferintalaclasadebazaaacesteia,dacaderivareaestedetippublicsinuexistaambiguitati.
2.Referintelenupotfiutilizate�nmecanismuldevirtualitatedeoareceeletrebuiesafieintia
lizateat�tladeclararec�tsilaconversie.
56
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISM
Exemplul1:
class A { public: virtual void arata(); //�n loc de void arata() // . . . . };
class B : virtual public A { public:virtual void arata(); //�nlocde
voidarata() // . . . . }; class C : virtual public A { public: virtual void
arata(); //�nlocde voidarata() // . . . . }; class D : public B, public
C{ public:virtual void arata(); //�nlocde voidarata() // . . . . };
57
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISM�n urma acestei modificari, rezultele executiei
programului anterior ar fi fost:intmain() {A u(10), *PA; // Constructor A 10 B
v1(9, 7), *PB; // Constructor A 9 Constructor B 7 -ptr. v1 C v2(8,12), *PC; //
Constructor A 8 Constructor C 12 -ptr. v2 D w(31, 9, 14, 35), *PD; // Constructor A
31 Constructor B 9 // Constructor C 14 Constructor D 35 PA=&u; PA->arata(); // Se
selecteaza metoda arata din clasa A A.a=10 PA=&v1; PA->arata(); // Se selecteaza
metoda arata din clasa B B.b=7 PB=&v1; PB->arata(); // Se selecteaza metoda arata
din clasa B B.b=7 PA=&w; PB=&w; PD=&w; u.arata(); // Apelul metodei arata ptr.
obiectul curent, clasa A A.a=10 PA->arata(); // Se selecteaza metoda arata din
clasa D D.d=35 PB->arata(); // Se selecteaza metoda arata din clasa D D.d=35 PD-
>arata(); // Se selecteaza metoda arata din clasa D D.d=35 }
58
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMObservatie:
1.Deoarecemetodaarataestevirtuala,s-
aselectatmetodapentruclasaobiectuluisprecarepointeazapointerul.2.Daca�nclasadebazas
edeclaraometodavirtuala,�nclaselederivatemetodelecuaceeasisemnaturavorficonsiderate
implicitvirtuale(chiardacaelenusuntdeclarate,explicit,virtuale).
59
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISM�ncazuluneifunctiideclaratevirtuala�nclasadebazasiredefinite�nclasaderiv
ata,redefinireametodei�nclasaderivataareprioritatefatadedefinireaeidinclasadebaza.A
stfel,ofunctievirtualadeclarata�nclasadebazaactioneazacaunsubstitutpentrupastraread
atelorcarespecificaoclasageneraladeactiunisideclaraformainterfetei.Laprimavedere,re
definireauneifunctiivirtuale�ntr-
oclasaderivataparesimilaracusupra�ncarcareauneifunctieiobisnuite.Totusi,nuesteasa,d
eoareceprototipuluneimetodevirtualeredefinitetrebuiesacoincidacucelspecificat�nclas
adebaza.�ncazulsupra�ncarcariiuneifunctiinormale,caracteristicileprototipurilortreb
uiesadifere(printipulreturnat,numarulsi/sautipulparametrilor).
60
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMDacaofunctieestedefinitacafunctievirtuala�nclasadebazasiredefinita�nclas
elederivate,laapelulacesteiacafunctiemembraaunuiobiectpentrucaresecunoasteunpointer
,seselecteazafunctiadupatipulobiectului,nualpointerului.Suntposibilemaimultesituati
i:
-Dacaobiectulestedetipclasadebazanusepoatefolosiunpointerlaoclasaderivata-
Dacaobiectulestedetipclasaderivatasipointerulestepointerlaclasaderivata,seselecteaz
afunctiaredefinita�nclasaderivatarespectiva.-
Dacaobiectulestedetipclasaderivata,iarpointerulfolositesteunpointerlaoclasadebazaaa
cesteia,seselecteazafunctiaredefinita�nclasaderivatacorespunzatoaretipuluiobiectulu
i.
61
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMAcestaestemecanismuldevirtualitatesielpermiteimplementareapolimorfismulu
i�nclaselederivate.Ofunctieredefinita�ntr-
oclasaderivatadominafunctiavirtualacorespunzatoaredinclasadebazasio�nlocuiestechiar
dacatipulpointeruluicucareesteaccesataestepointerlaclasadebaza.Polimorfismul,adicaa
peluluneifunctiidintr-
oclasaderivataprinpointerdetipclasadebaza,esteposibilnumaiprinutilizareapointerilor
laobiecte.
62
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMMetodevirtualepure
�nunelesituatii,oclasadebaza(dincaresederiveazaalteclase)auneiierarhii,poatefiat�td
egenerala,astfel�nc�tunelemetodenupotfidescriselaacestnivel(at�tdeabstract),cidoar�
nclaselederivate.Acestemetodesenumescfunctiipure.Metodelevirtualepuresuntmetodecare
sedeclara,nusedefinesclaacestniveldeabstractizare.
63
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMMetodevirtualepure
Metodelevirtualepuresuntmetodecaresedeclara,nusedefinesclaacestniveldeabstractizare
.Ometodavirtualapuratrebuiesafieprezenta�noriceclasaderivata.Ofunctievirtualapuraes
teofunctiecarenuaredefinitie�nclasadebaza,iardeclaratiaeiarata�nfelulurmator:
virtual<tip_ret> <nume_functie>(<lista_decl_pf>) = 0;
64
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMExemple:
classbaza{public:virtualvoidvirt_f()=0;//metodavirt_festemetodavirtualapura;}classv
ietuitoare{public:virtualvoidnutritie()=0;//nutritieestemetodavirtualapura};
65
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMOclasacucelputinometodavirtualapurasenumesteclasaabstracta(clasavietuito
areesteabstractasi,caurmare,nupoatefiinstantiata).Deoareceoclasaabstractacontineuna
saumaimultefunctiipentrucarenuexistadefinitii(functiivirtualepure),nupotficreateins
tante(obiecte)dinaceaclasa,darpotficreatipointerisireferintelaastfeldeclaseabstract
e.Oclasaabstractaestefolosita�ngeneralcaoclasafundamentala,dincareseconstruiescalte
claseprinderivare;constituieuncadrusuportdelacaresaseponrneasca�ndefinireaobiectelo
r.Claseleabstracteauroluldeaajutalaorganizareastructurii(retelei)demostenire.
PROGRAMAREACALCULATOARELORSILIMBAJEDE PROGRAMAREII
66
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMCompilatorulnupermitecreareadeobiectedinclasaabstracta,cidoardinclaseled
erivate,cuconditiacaacesteclasederivatesafurnizezeimplementarialefunctiilevirtualep
ure.Functiilevirtualepuresemostenesccasifunctiilevirtualeobisnuite.Orice clasa
derivata dintr-o clasa abstracta este, la r�ndul ei clasaabstracta(si deci nu se
pot crea instante ale acesteia) dacanu se redefinesctoate functiile virtuale pure
mostenite. Daca o clasa redefineste toate functiile virtuale pure ale claselor ei
de baza, devine clasa normala (ne-abstracta) si pot fi create instante (obiecte)
ale acesteia.
1
67
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMExemplul7: Program de conversiea unordate
dintr-o valoarede intrare�ntr-o
valoarede iesire; de exemplu, din grade Farenheit�ngrade Celsius, din inch
�ncentimetri, etc. classConvert{ protected: double x; // valoareintraredouble y; //
valoareiesirepublic: Convert(double i){x = i;} double getx(){return x;} double
gety(){return y;} virtualvoid conv() = 0; //functievirtualapura}; Clasa de baza
abstracta Converteste folosita pentru crearea prin derivare a unei clase specifice
fiecarui tip de conversie de date dorit. Aceasta clasa defineste datele comune,
necesare oricarui tip de conversie preconizat, de la o valoare de intrare x la o
valoare de iesire y. Functia de conversie conv() nu se poate defini �n clasa
de baza, ea fiind specifica fiecarui tip de conversie �n parte; de aceea functia
conv( ) se declara functie virtuala purasi trebuie sa fie redefinita �n fiecare
clasa derivata.
68
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMclassFC: public Convert{ // clasaFC de
conversiegrade Farenheitin grade Celsius public: FC(double i):Convert(i){} void
conv(){y = (x-32)/1.8;} }; classIC: public Convert{ // clasaIC de conversieinch in
centimetripublic: IC(double i):Convert(i){} void conv(){y = 2.54*x;} };
69
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMintmain (){ Convert* p = 0; // pointer la
bazacout<<"Introduceti valoarea si tipul conversiei: "; double v; char ch; cin>> v
>> ch; switch (ch){ case 'i': //conversieinch -> cm (clasaIC) p = new IC(v); break;
case 'f': //conv. Farenheit-> Celsius (clasaFC) p = new FC(v); break; } if (p){ p-
>conv(); cout<< p->getx() << "---> " << p->gety()<< endl; delete p; } } �n functia
main() se executa o conversie a unei valori introduse de la consola, folosind un
tip de conversie (o clasa derivata) care se selecteaza pe baza unui caracter
introdus la consola.
70
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMAcestaesteunexemplu�ncareestedestuldepregnantanecesitateafunctiilorvirtu
ale:deoarecenusecunoaste�nmomentulcompilariitipuldeconversiecaresevaefectua,sefolos
esteunpointerlaclasadebazapentruoriceoperatie(creareaunuiobiectdeconversienou,apelu
lfunctieiconv(),afisarearezultatelor,distrugereaobiectuluilaterminareaprogramului).
Singuradiferentierecarepermiteselectiacorectaafunctiilor,estetipulobiectuluicreat,c
aredepindedetipulconversieicerutedelaconsola.
71
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISM�nacestmomentsepotprecizamaidetaliatasemanarilesidiferenteledintre:?
functiilesupra�ncarcate(overloaded),?functiileredefinite(redefined)si?
functiilevirtualeredefinite(overrided).�ntoateacestesituatiinumelefunctiiloresteace
lasi.
72
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISM�ncazulfunctiilorsupra�ncarcate,listadeargumentetrebuiesadifereastfel�nc
�tselectiauneivarianteafunctieisapoatafifacutafaraambiguitatedupatipulargumentelord
eapel.Functiileredefinitesifunctiilevirtualeredefinitetrebuiesaaibaacelasiprototip.
Dintremaimultefunctii(ofunctiedefinitavirtual�nclasadebazasiredefinita�nclaselederi
vate),selectiavarianteifunctieisefacedupatipulobiectuluipentrucareesteinvocata.Dint
remaimultefunctiinevirtuale(ofunctiedefinitafaraspecificatorulvirtual�nclasadebazas
iredefinita�nclaselederivate),selectiavarianteifunctieisefacedupatipulpointeruluicu
careesteinvocata.
73
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMPolimorfismAsacumauilustratexempleleanterioare,ofunctievirtualadeclarata
�nclasadebazaactioneazacaunsubstitutpentrupastrareadatelorcarespecificaoclasagenera
ladeactiunisideclaraformauneiinterfetecomune,iarfunctiileredefinite�nclaselederivat
eprecizeazaactiunilespecificefiecareiclasederivate(metodespecificediferitelorfuncti
onalitati).Obiectelecuaceeasiinterfatapotfisubstituiteunulaltuialaruntime(obiectele
sevorcomporta�nfunctiedetipullor).Aceastacomportare,careasigurasimplificareasiorgan
izareasistemelordeprogramecomplexe,estecunoscutasubnumeledepolimorfism.
74
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI POLIMORFISMPolimorfism
Polimorfismulintrodusprinmecanismuldevirtualitateestepolimorfismlaniveldeexecutie,c
arepermitelegareat�rzie(latebinding)�ntreevenimenteledinprogram,�ncontrastculegarea
timpurie(earlybinding),proprieapelurilorfunctiilornormale(nevirtuale).
1.Conceptede bazaale programariiorientate
peobiecte2.Clasesiobiecte3.Supraincarcareaoperatorilor4.Creareaierarhiilorde
clase5.Operatiide intrare/ iesirein limbajulC++6.Implementariale modelelorde
date7.Functiisiclasegenerice8.ExceptiisitratareaacestoraCuprinsulCursului
75
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMIntercorelarea(legarea)timpuriesereferalaevenimentelecaresedesfasoara�nt
impulcompilarii:apeluridefunctiipentrucaresuntcunoscuteadreseledeapel(functiinormal
e,functiisupra�ncarcate,operatorisupra�ncarcati,functiimembrenevirtuale,functiifrie
nd).Apelurilerezolvate�ntimpulcompilariibeneficiazadeoeficientaridicata.
2
76
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMTermenuldelegaret�rziesereferalaevenimentedintimpulexecutiei.�nastfeldea
peluri,adresafunctieicareurmeazasafieapelatanuestecunoscutadec�t�nmomentulexecutiei
programului.Functiilevirtualesuntevenimenteculegaret�rzie:accesullaastfeldefunctiis
efaceprinpointerlaclasadebaza,iarapelareaefectivaafunctieiestedeterminata�ntimpulex
ecutieidetipulobiectuluiindicat,pentrucareestecunoscutpointerullaclasasadebaza.
Programareacalculatoarelorsilimbajede programareII
77
CAP. 4Creareaierarhiilorde clase
4.7. FUNCTII VIRTUALE SI
POLIMORFISMAvantajulprincipalallegariit�rzii(permisadepolimorfismulasiguratdefuncti
ilevirtuale)�lconstituesimplitateasiflexibilitateaprogramelorrezultate.Bine�nteles,
existasidezavantaje,celmaiimportantfiindtimpulsuplimentarnecesarselectieifunctieiap
elateefectivdintimpulexecutiei,ceeaceconducelauntimpdeexecutiemaimarealprogramelor.
Cualtecuvinte,folosireafunctiilorvirtualetrebuierezervatanumaipentrusituatii�ncares
unt�nmodrealnecesare,atuncic�ndbeneficiuladusdepolimorfismdepasestecostulsuplimenta
rdeexecutie.
78
CAP. 4
SFARSITUL Capitolului4
Creareaierarhiilorde clase

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