Sunteți pe pagina 1din 24

Programare orientata pe obiecte

Curs 8 – Mostenire – problema diamantului

C
++{};
C++ Acest curs
› Mostenire – problema diamantului
› Polimorfism
C++ Controlul accesului la membri clasei de bază
C++ Moştenirea multiplă - probleme
› Moştenire în formă de diamant
› O clasă moşteneşte 2 clase care au o funcţie membră cu aceaşi semnătură
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
› Fie următoarea ierarhie de clase
class A
{
protected:
int x;
public:
A(void) {x = 0; cout << "A()\n";}
A(int xx) {x = xx; cout << "A(int)\n";}
~A(void) {cout << "~A()\n";}
};
class B: public A
{
public:
B(void){cout << "B()\n";}
B(int xx): A(x) {cout << "B(int)\n";}
~B(void) {cout << "~B()" << endl;}
};
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
class C: public A
{
public:
C(void){ cout << "C()\n";}
C(int xx) : A(xx) {cout << "C(int)\n";}
~C(void) {cout << "~C()\n";}
};
class D: public B, public C
{
public:
D(int xx): B(xx), C() {cout << "D(int)\n";}
~D(void) {cout << "~D()\n";}
void Print(void) {cout << x <<endl;};
};
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
int main (void)
{
A a(6); B b(7); C c(8); D d(5);
d.Print();
cout <<"sizeof(a)="<<sizeof(a)<<endl;
cout <<"sizeof(b)="<<sizeof(b)<<endl;
cout <<"sizeof(c)="<<sizeof(c)<<endl;
cout <<"sizeof(d)="<<sizeof(d)<<endl;
return 0;
}
› Compilare:
error C2385: ambiguous access of 'x' in 'D'

› Posibile „soluţii” de implementare ale funcţiei D::Print():


void D::Print(void) {cout << A::x <<endl;}; //se afiseaza 5
void D::Print(void) {cout << B::x <<endl;}; //se afiseaza 5
void D::Print(void) {cout << C::x <<endl;}; //se afiseaza 0
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
› Dimensiuni ale obiectelor:
sizeof(a) = 4
sizeof(b) = 4
sizeof(c) = 4
sizeof(d) = 8
A(int)
› Apelarea constructorilor: B(int)
A()
C()
D(int)
0
sizeof(d)=8
~D()
~C()
~A()
~B()
~A()
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
› Pentru rezolvarea cazului de ambiguitate se declara clasa A virtuala
astfel încât constructorul clasei virtuale va fi apelat prima dată şi apoi,
celelalte apeluri explicite ale constructorului clasei virtuale vor fi ignorate
class B: public virtual A
{
public:
B(void){cout << "B()\n";}
B(int x): A(x) {cout << "B(int)\n";}
~B(void) {cout << "~B()";}
};
class C: virtual public A
{
public:
C(void){cout << "C()\n";}
C(int x): A(x) {cout << "C(int)\n";}
~C(void) {cout << "~C()\n";}
};
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
› Apel main: A()
B(int)
C()
D(int)
D::x=0
sizeof(d)=16
~D()
~C()
~B()
~A()

› Pentru a se forţa apelarea constructorului de initializare, se


reimplementează constructorul de iniţializare al clasei D.
class D: public B, public C {
public:
D(int x): A(x) {cout << "D(int)\n";}
~D(void) {cout << "~D()\n"; }
void Print(void){cout << x << endl;};
};
Moştenirea multiplă – studiu de caz
C++ Problema diamantului
› Apel main:
A(int)
B()
C()
D(int)
D::x=5
sizeof(d)=12
~D()
~C()
~B()
~A()
O clasă moşteneşte 2 clase care au o funcţie
C++ membră cu aceaşi semnătură
d.Print();
//...

error C2385: ambiguous access of 'Print' in 'D'

› Soluţii:
– redefinirea funcţiei respective în clasa derivată
void D::Print(void)
{
cout << "D::x=" <<x<< endl;
}
– utilizarea operatorului de rezoluţie apartenenţă la domeniu pentru
a specifica in mod clar domeniul de care aparţine funcţia
d.B::Print();
C++ Ierarhii de clase
› Odată cu moştenirea trebuie rezolvată o problemă: Având un pointer la
clasa de bază (Base*), cărei clase derivate aparţine obiectul pointat. Sunt 4
soluţii:
– Asigura-te că pointerul pointează către obiecte de acelaşi tip (nu se recomandă dar
poate fi o soluţie pentru containere omogene)
– Plasarea unui membru în clasa de bază pentru a caracteriza tipul de date.
– A se utiliza dynamic_cast pentru convertirea pointerului
– A se utiliza funcţii virtuale
class Angajat
{
protected:
enum TipAngajat{man, ang};
TipAngajat angType;
public:
Angajat(void): angType(ang){/*…*/};
//…
};
C++ Ierarhii de clase
class Manager : public Angajat{
//…
public:
Manager(void){angType=man; /*…*/};
//…
};
void Angajat::Print(void) const {
switch(angType) {
case ang:
cout << "Angajat -> Nume: " << firstName << " " <<
middleInitial << ". " << familyName << " \n";
break;
case man:
cout << "Manager -> Nume: " << firstName << " " <<
middleInitial << ". " << familyName;
const Manager*p = static_cast<const Manager*>(this);
cout << ", level" << (((Manager&))(*p)).GetLevel() <<"\n";
break;
}
C++ Ierarhii de clase
int main(void)
{
Date da(5,10,1977);
Date dm(10,5,1968);
cout<<"*******************************************\n";

Manager m("Gica", "Popescu", 'G', dm, 3, 10, 8);


Angajat a("Mitica", "Gheorghe", 'I', da, 1);

Angajat *pa;
pa = &a;
pa->Print();

pa = &m;
pa->Print();

return 0;
}
C++ Ierarhii de clase
Apel main:
Angajat -> Nume: Mitica I. Gheorghe
Manager -> Nume: Gica G. Popescu, level 8

› Această soluţie nu se recomandă deoarece prezintă probleme de


întreţinere, fiind o soluţie generatoare de erori
C++ Funcţii virtuale
› Utilizarea funcţiilor virtuale elimină problemele generate de soluţia cu
membru de caracterizare a tipului obiectului, permiţând programatorului
să declare funcţii în clasa de bază ce pot fi redefinite în fiecare clasă
› Compilatorul şi linkeditorul va garanta corespondenţa corectă între
obiecte şi funcţiile aferente.
class Angajat
{
private:
//…
public:
//…
virtual void Print(void)const;
};
C++ Funcţii virtuale
int main(void) {
Date da(5,10,1977);
Date dm(10,5,1968);

cout<<"**********************************************\n";
Manager m("Gica", "Popescu", 'G', dm, 3, 10, 8);
Angajat a("Mitica", "Gheorghe", 'I', da, 1 );

Angajat *pa;
pa = &a;
cout << "Angajat -> ";
pa->Print();

pa = &m;
std::cout << "Manager -> ";
pa->Print();

return 0;
}
C++ Funcţii virtuale
› Cuvântul cheie virtual indică faptul că Print() se comportă ca o interfaţă
atât pentru funcţia Print() definită în clasa Angajat cât şi pentru funcţia
Print() definită în clasa Manager derivată din Angajat.
› Compilatorul va asigura că pentru un obiect Angajat va fi apelată funcţia
Print() corespunzătoare, dacă în clasele derivate aceasta a fost definită.
› Toate funcţiile Print() redefinite trebuie să aibă aceeaşi semnătură
› O funcţie virtuală trebuie definită în clasa unde a fost declarată (cu excepţia
cazurilor când sunt declarate ca fiind virtuale pure)
› Determinarea funcţiei Print() corespunzătoare, independent de tipul
Angajat-ului se numeşte polimorfism.
C++ Polimorfism
› Un tip de date cu funcţii virtuale se numeşte tip de date polimorfic sau mai
exact run-time polimorphic type.
› Pentru a obţine un comportament polimorfic obiectele trebuie manipulate
prin intermediul pointerilor sau referinţelor
› O funcţie ce suprascrie o funcţie virtuală devine la rândul ei virtuală.
› Pentru a implementa polimorfismul, compilatorul trebuie să reţină unele
informaţii în fiecare obiect de tip Angajat şi să le folosească pentru a apela
funcţia Print() corespunzătoare.
› Conectarea unui apel al unei funcţii de corpul acesteia se numeşte legătura
C++ Polimorfism
› Când legătura se realizează înainte de rularea unui program(de către
compilator şi linkeditor), se numeşte legare timpurie sau legare statică
(early binding)
› Legarea implicită în C++ este cea statică
› Polimorfismul este un mecanism prin care legarea dintre apelul unei metode
şi corpul acesteia se face la momentul rulării (legarea dinamică) (late
binding)
› În mod uzual compilatorul converteşte numele unei funcţii virtuale într-un
index din cadrul unui tabel de pointeri la funcţii. Acel tabel este numit tabelul
cu funcţii virtuale sau mai simplu vftbl.
› Fiecare clasă cu funcţii virtuale are propriul său vftbl
C++ Tabela funcţiilor virtuale
C++ Tabela funcţiilor virtuale
› Conţine pointeri către funcţiile virtuale
› Este creată pentru fiecare clasă ce conţine funcţii membre virtuale sau
suprascrie funcţii virtuale
› Există numai una pentru o anumită clasă
› Există clase pentru care nu este creată
› Când un obiect este creat, se adaugă un membru ascuns, un pointer către
această tabelă virtuală
› Compilatorul generează automat codul în constructori pentru iniţializarea
pointerului către această tabelă
› Se accesează în momentul cănd se execută o funcţie virtuală

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

  • Test Grila Poo Csie
    Test Grila Poo Csie
    Document11 pagini
    Test Grila Poo Csie
    Cristi Marinescu
    100% (1)
  • Admitere Informatica Online Subiecte
    Admitere Informatica Online Subiecte
    Document54 pagini
    Admitere Informatica Online Subiecte
    georgianaeleve1
    Încă nu există evaluări
  • C
    C
    Document158 pagini
    C
    Eugen1968
    100% (1)
  • Rezolvari PP
    Rezolvari PP
    Document30 pagini
    Rezolvari PP
    msiulian
    0% (1)
  • Rezolvari Programare Procedurala
    Rezolvari Programare Procedurala
    Document53 pagini
    Rezolvari Programare Procedurala
    micklamickla
    100% (1)
  • Grile Subprograme1
    Grile Subprograme1
    Document7 pagini
    Grile Subprograme1
    tresttia_tresttia
    Încă nu există evaluări
  • Kis Alexandru Lab 11
    Kis Alexandru Lab 11
    Document8 pagini
    Kis Alexandru Lab 11
    Sabine Crihan
    Încă nu există evaluări
  • Aplicaţii POO
    Aplicaţii POO
    Document6 pagini
    Aplicaţii POO
    Neti Georgiana Sechila
    Încă nu există evaluări
  • POO - Ex202 - 12
    POO - Ex202 - 12
    Document4 pagini
    POO - Ex202 - 12
    Cristina Maria
    Încă nu există evaluări
  • POO - Ex201 - 12
    POO - Ex201 - 12
    Document4 pagini
    POO - Ex201 - 12
    Cristina Maria
    Încă nu există evaluări
  • 4 Proiectare Si Programare Orientata Obiect Rezolvate
    4 Proiectare Si Programare Orientata Obiect Rezolvate
    Document17 pagini
    4 Proiectare Si Programare Orientata Obiect Rezolvate
    Doru Barbu
    100% (3)
  • Ex210 12
    Ex210 12
    Document4 pagini
    Ex210 12
    Cristina Maria
    Încă nu există evaluări
  • Poo Test Grila Cu Rezultate PDF
    Poo Test Grila Cu Rezultate PDF
    Document5 pagini
    Poo Test Grila Cu Rezultate PDF
    gcostea32
    Încă nu există evaluări
  • POO - Ex209 - 12
    POO - Ex209 - 12
    Document4 pagini
    POO - Ex209 - 12
    Cristina Maria
    Încă nu există evaluări
  • Activitati 04 - Elementele Limbajului C#
    Activitati 04 - Elementele Limbajului C#
    Document15 pagini
    Activitati 04 - Elementele Limbajului C#
    Catalina Brindas
    Încă nu există evaluări
  • Curs 1 Informatica
    Curs 1 Informatica
    Document43 pagini
    Curs 1 Informatica
    Gherghel Musat Daniel Emil
    Încă nu există evaluări
  • C2 Poo Acs
    C2 Poo Acs
    Document47 pagini
    C2 Poo Acs
    Vlad Raducan
    Încă nu există evaluări
  • Test10csem2 PDF
    Test10csem2 PDF
    Document2 pagini
    Test10csem2 PDF
    Tatiana Purcareata
    Încă nu există evaluări
  • OOP Exemple Subiecte Posibile
    OOP Exemple Subiecte Posibile
    Document5 pagini
    OOP Exemple Subiecte Posibile
    Popescu Andreea
    Încă nu există evaluări
  • Admitere Informatica Online Subiecte-V2
    Admitere Informatica Online Subiecte-V2
    Document51 pagini
    Admitere Informatica Online Subiecte-V2
    ionut ionescu
    Încă nu există evaluări
  • Programare Orientata Pe Obiecte - Poo - : Titular Curs: Contact: Birou
    Programare Orientata Pe Obiecte - Poo - : Titular Curs: Contact: Birou
    Document52 pagini
    Programare Orientata Pe Obiecte - Poo - : Titular Curs: Contact: Birou
    Teodora Dan
    Încă nu există evaluări
  • 2 Informatică 1
    2 Informatică 1
    Document2 pagini
    2 Informatică 1
    Alexandra Burcea
    Încă nu există evaluări
  • Subiecte Avansate C++: Dorin Mancu
    Subiecte Avansate C++: Dorin Mancu
    Document93 pagini
    Subiecte Avansate C++: Dorin Mancu
    Liliana
    Încă nu există evaluări
  • An1 Lab05 Sem2 21-22
    An1 Lab05 Sem2 21-22
    Document7 pagini
    An1 Lab05 Sem2 21-22
    sabina
    Încă nu există evaluări
  • Lab 4 POO
    Lab 4 POO
    Document6 pagini
    Lab 4 POO
    Catalin Morari
    Încă nu există evaluări
  • Lab 3
    Lab 3
    Document26 pagini
    Lab 3
    cojucari dumitru
    Încă nu există evaluări
  • Raport Lab1
    Raport Lab1
    Document5 pagini
    Raport Lab1
    Tabureanu Marian
    Încă nu există evaluări
  • Lab 2
    Lab 2
    Document5 pagini
    Lab 2
    Daniel Popa
    Încă nu există evaluări
  • Adul 2
    Adul 2
    Document1 pagină
    Adul 2
    Ghilea Andrei
    Încă nu există evaluări
  • An1 Lab08 Sem2 20-21
    An1 Lab08 Sem2 20-21
    Document7 pagini
    An1 Lab08 Sem2 20-21
    Ioana
    Încă nu există evaluări
  • Modele Admitere Informatica 2022
    Modele Admitere Informatica 2022
    Document11 pagini
    Modele Admitere Informatica 2022
    Gina Crihană
    Încă nu există evaluări
  • oop_partea2_studii_de_Caz_
    oop_partea2_studii_de_Caz_
    Document15 pagini
    oop_partea2_studii_de_Caz_
    SicKu Eu
    Încă nu există evaluări
  • Exercitii C++
    Exercitii C++
    Document3 pagini
    Exercitii C++
    Cezar Barbu
    Încă nu există evaluări
  • Admitere_2
    Admitere_2
    Document6 pagini
    Admitere_2
    roberttopa61
    Încă nu există evaluări
  • Test 1
    Test 1
    Document3 pagini
    Test 1
    Nur daud Mounaged
    Încă nu există evaluări
  • Kis Alexandru Lab 5
    Kis Alexandru Lab 5
    Document10 pagini
    Kis Alexandru Lab 5
    Sabine Crihan
    100% (1)
  • vt raport pc (2)
    vt raport pc (2)
    Document6 pagini
    vt raport pc (2)
    Олежа CS1.6
    Încă nu există evaluări
  • Var19 20
    Var19 20
    Document11 pagini
    Var19 20
    Ion Ionescu
    Încă nu există evaluări
  • Academia Navala 2023 Subiecte
    Academia Navala 2023 Subiecte
    Document5 pagini
    Academia Navala 2023 Subiecte
    roberttopa61
    Încă nu există evaluări
  • Informatica Bacalaureat
    Informatica Bacalaureat
    Document2 pagini
    Informatica Bacalaureat
    Andrei Beres
    Încă nu există evaluări
  • Raport Lab1
    Raport Lab1
    Document5 pagini
    Raport Lab1
    Tabureanu Marian
    Încă nu există evaluări
  • Admitere 10
    Admitere 10
    Document8 pagini
    Admitere 10
    Amelia Pop
    Încă nu există evaluări
  • Lab11 s1 An1 21 22
    Lab11 s1 An1 21 22
    Document11 pagini
    Lab11 s1 An1 21 22
    David Adrian Cioloca
    Încă nu există evaluări
  • Test de antrenament 7 2020
    Test de antrenament 7 2020
    Document4 pagini
    Test de antrenament 7 2020
    Ábrahám
    Încă nu există evaluări
  • LAB1 Poo
    LAB1 Poo
    Document6 pagini
    LAB1 Poo
    Cristian Conea
    Încă nu există evaluări
  • Curs CodeBlocksDownload
    Curs CodeBlocksDownload
    Document131 pagini
    Curs CodeBlocksDownload
    Adi Gabriel
    Încă nu există evaluări
  • Griles
    Griles
    Document7 pagini
    Griles
    PadurariuTeofil
    Încă nu există evaluări
  • Info Model7 Test AC Enunturi
    Info Model7 Test AC Enunturi
    Document8 pagini
    Info Model7 Test AC Enunturi
    ana
    Încă nu există evaluări
  • Kis Alexandru Lab 6
    Kis Alexandru Lab 6
    Document7 pagini
    Kis Alexandru Lab 6
    Sabine Crihan
    Încă nu există evaluări
  • PooC11 2018
    PooC11 2018
    Document76 pagini
    PooC11 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC04 2018
    PooC04 2018
    Document35 pagini
    PooC04 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC06 2018
    PooC06 2018
    Document34 pagini
    PooC06 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC01 2018
    PooC01 2018
    Document51 pagini
    PooC01 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC05 2018
    PooC05 2018
    Document22 pagini
    PooC05 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC13 2018
    PooC13 2018
    Document47 pagini
    PooC13 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC02 2018
    PooC02 2018
    Document46 pagini
    PooC02 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC14 2018
    PooC14 2018
    Document22 pagini
    PooC14 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC09 2018
    PooC09 2018
    Document22 pagini
    PooC09 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC03 2018
    PooC03 2018
    Document49 pagini
    PooC03 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC07 2018
    PooC07 2018
    Document29 pagini
    PooC07 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC04 2018
    PooC04 2018
    Document35 pagini
    PooC04 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC03 2018
    PooC03 2018
    Document49 pagini
    PooC03 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC09 SDL
    PooC09 SDL
    Document20 pagini
    PooC09 SDL
    Ciulei Virgil
    Încă nu există evaluări
  • PooC02 2018
    PooC02 2018
    Document46 pagini
    PooC02 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC01 2018
    PooC01 2018
    Document51 pagini
    PooC01 2018
    Ciulei Virgil
    Încă nu există evaluări
  • PooC05 2018
    PooC05 2018
    Document22 pagini
    PooC05 2018
    Ciulei Virgil
    Încă nu există evaluări