This shows you the differences between two versions of the page.
poo-is:laboratoare:07 [2020/09/27 17:20] ruben_gilian.udroiu [Legarea Statica] |
poo-is:laboratoare:07 [2020/09/30 17:27] (current) alexandru.ionita99 |
||
---|---|---|---|
Line 5: | Line 5: | ||
* Capitolul 15 (Chapter 15: Polymorphism and Virtual Functions, pag. 661 - 693) | * Capitolul 15 (Chapter 15: Polymorphism and Virtual Functions, pag. 661 - 693) | ||
- | ====== Introducere ====== | + | ===== 1. Introducere ===== |
<note important>**Functiile virtuale** permit claselor derivate sa inlocuiasca implementarea metodelor din clasa de baza - **suprascriere/supraincarcare/override**- si pun la dispozitie mecanismul de legare dinamica.</note> | <note important>**Functiile virtuale** permit claselor derivate sa inlocuiasca implementarea metodelor din clasa de baza - **suprascriere/supraincarcare/override**- si pun la dispozitie mecanismul de legare dinamica.</note> | ||
O functie virtuala este membra a clasei de baza si este redefinita(overriden) de o clasa derivata. | O functie virtuala este membra a clasei de baza si este redefinita(overriden) de o clasa derivata. | ||
Line 17: | Line 17: | ||
- | ====== Legarea Statica ====== | + | ===== 2. Legarea Statica ===== |
Line 82: | Line 82: | ||
<note warning>**Dar** | <note warning>**Dar** | ||
* aceasta solutie nu e robusta | * aceasta solutie nu e robusta | ||
- | * trebuie mereu sa ne punem problema catre ce tip de obiect pointeaza pointerul | + | * trebuie mereu sa ne punem problema catre ce tip de obiect pointeaza pointerul de tip clasa de baza si sa facem conversii explicite pentru a apela functia dorita |
- | de tip clasa de baza si sa facem conversii explicite pentru a apela functia dorita | + | |
* e predispusa erorilor logice | * e predispusa erorilor logice | ||
</note> | </note> | ||
Line 91: | Line 90: | ||
- | ====== Legarea Dinamica ====== | + | ===== 3. Legarea Dinamica ===== |
**Legare dinamica/tarzie(Late binding):** | **Legare dinamica/tarzie(Late binding):** | ||
Line 141: | Line 140: | ||
Dar cum reuseste acesta sa puna in actiune toate mecanismele necesare realizarii de legaturi | Dar cum reuseste acesta sa puna in actiune toate mecanismele necesare realizarii de legaturi | ||
dinamice? | dinamice? | ||
- | <note tip>Pentru aceasta compilatorul creeaza un tabel numit **VTABLE** pentru fiecare clasa care | + | <note tip>Pentru aceasta, compilatorul creeaza un tabel numit **VTABLE** pentru fiecare clasa care |
contine macar o functie virtuala. | contine macar o functie virtuala. | ||
Line 162: | Line 161: | ||
- | ====== Polimorfism si functii virtuale ====== | + | ===== 4. Polimorfism si functii virtuale ===== |
- | <note>“poli” – mai multe;“morf” –forma | + | <note>“poli” – mai multe; “morf” – forma |
</note> | </note> | ||
**Polimorfismul** se poate realiza prin: | **Polimorfismul** se poate realiza prin: | ||
- | * **supradefinirea functiilor** - functii cu acelasi nume, dar semnaturi diferite - care | + | * **supradefinirea functiilor** - functii cu acelasi nume, dar semnaturi diferite - care se comporta diferit in functie de context – in functie de modul in care sunt apelate – chiar daca au acelasi nume; **polimorfism ad hoc** |
- | se comporta diferit in functie de context – in functie de modul in care sunt | + | |
- | apelate – chiar daca au acelasi nume; **polimorfism ad hoc** | + | * **suprascrierea functiilor** – functii virtuale: acelasi pointer poate sa aiba comportamente diferite la apelul unei metode, in functie de tipul lui dinamic |
- | * **suprascrierea functiilor** – functii virtuale: acelasi pointer poate sa aiba | + | |
- | comportamente diferite la apelul unei metode, in functie de tipul lui dinamic | + | |
<note>**Avand in vedere importanta lor, de ce nu folosim exclusiv functii virtuale? De ce nu | <note>**Avand in vedere importanta lor, de ce nu folosim exclusiv functii virtuale? De ce nu | ||
Line 186: | Line 183: | ||
**Cand este important acest mecanism?** | **Cand este important acest mecanism?** | ||
- | 1. Functiile virtuale sunt folosite pentru a implementa polimorfismul in momentul | + | - Functiile virtuale sunt folosite pentru a implementa polimorfismul in momentul rularii (" Run time Polymorphism“) |
- | rularii (" Run time Polymorphism“) | + | - Un alt avantaj al functiilor virtuale este ca permit realizarea de liste neomogene de obiecte (exemplul de la finalul cursului C6) |
- | + | - Dezvoltarea de biblioteci in spiritul POO. | |
- | 2. Ordered List ItemUn alt avantaj al functiilor virtuale este ca permit realizarea de liste neomogene | + | |
- | de obiecte (exemplul de la finalul cursului C6) | + | |
- | + | ||
- | 3. Ordered List ItemDezvoltarea de biblioteci in spiritul POO. | + | |
</note> | </note> | ||
Line 201: | Line 194: | ||
#include <iostream> | #include <iostream> | ||
using namespace std; | using namespace std; | ||
- | class Baza | + | class Baza{ |
- | {protected: | + | protected: |
- | int atr1; | + | int atr1; |
- | public: | + | public: |
- | Baza(); | + | Baza(); |
- | Baza(int ); | + | Baza(int ); |
- | void set_atr1(int ); | + | void set_atr1(int ); |
- | **virtual** void afisare(); | + | virtual void afisare(); |
- | **virtual** ~Baza(){}; | + | virtual ~Baza(){}; |
}; | }; | ||
</code> | </code> | ||
Line 215: | Line 208: | ||
<code c++ Baza.cpp> | <code c++ Baza.cpp> | ||
#include "Baza.h" | #include "Baza.h" | ||
- | Baza::Baza() { } | + | Baza::Baza() { } |
- | Baza::Baza(int i):atr1(i) { } | + | Baza::Baza(int i):atr1(i) { } |
- | void Baza::set_atr1(int i) { atr1=i; } | + | void Baza::set_atr1(int i) { |
- | void Baza::afisare() { cout << "atr1 = " << atr1<<endl; } | + | atr1 = i; |
+ | } | ||
+ | void Baza::afisare() { | ||
+ | cout << "atr1 = " << atr1 << endl; | ||
+ | } | ||
</code> | </code> | ||
Line 224: | Line 221: | ||
#pragma once | #pragma once | ||
#include "Baza.h" | #include "Baza.h" | ||
- | class Derivata: public Baza | + | class Derivata : public Baza { |
- | { | + | protected: |
- | protected: int atr2; | + | int atr2; |
- | public: | + | public: |
- | Derivata(); | + | Derivata(); |
- | Derivata(int , int ); | + | Derivata(int , int ); |
- | void set_atr2(int ); | + | void set_atr2(int ); |
- | void afisare(); //afisare din Derivata e virtuala | + | void afisare(); //afisare din Derivata e virtuala |
};//destructorul generat automat e virtual | };//destructorul generat automat e virtual | ||
</code> | </code> | ||
- | <code c++ main.cpp> | + | <code c++ Derivata.cpp> |
#include "Derivata.h" | #include "Derivata.h" | ||
- | Derivata::Derivata() { } | + | Derivata::Derivata() { } |
- | Derivata::Derivata(int a1, int a2):Baza(a1),atr2(a2) { } | + | Derivata::Derivata(int a1, int a2):Baza(a1),atr2(a2) { } |
- | void Derivata::set_atr2(int n) { atr2 = n; } | + | void Derivata::set_atr2(int n) { |
- | void Derivata::afisare() | + | atr2 = n; |
- | { Baza::afisare(); | + | } |
- | cout << "atr2 = " << atr2<<endl; | + | void Derivata::afisare() { |
- | } | + | Baza::afisare(); |
+ | cout << "atr2 = " << atr2 << endl; | ||
+ | } | ||
</code> | </code> | ||
- | <code c++ Derivata.cpp> | + | <code c++ main.cpp> |
#include "Derivata.h" | #include "Derivata.h" | ||
- | int main(int argc, char *argv[]) | + | int main(int argc, char *argv[]) { |
- | { | + | int n; |
- | int n; | + | cout << "Dati dimensiunea"; |
- | cout<<"Dati dimensiunea"; | + | cin >> n; |
- | cin>>n; | + | Baza **vec = new Baza*[n]; |
- | **Baza ****vec=new **Baza***[n]; | + | for (int i = 0; i < n; i++){ |
- | for (int i=0;i<n;i++){ | + | cout << "Introduceti obiect de tip Baza(0) sau Derivata(1)?"; |
- | cout<<"Introduceti obiect de tip Baza(0) sau Derivata(1)?"; | + | int tip; |
- | int tip; | + | cin >> tip; |
- | cin>>tip; | + | if (tip == 0){ |
- | if (tip==0){ | + | cout << "Dati atr1:"; |
- | cout<<"Dati atr1:"; | + | int a1; |
- | int a1; | + | cin >> a1; |
- | cin>>a1; | + | vec[i] = new Baza(a1); |
- | vec[i]=**new Baza(a1)**; | + | } |
- | }else if (tip==1){ | + | else if (tip == 1){ |
- | cout<<"Dati atr1 si atr2:"; | + | cout << "Dati atr1 si atr2:"; |
- | int a1,a2; | + | int a1, a2; |
- | cin>>a1; cin>>a2; | + | cin >> a1; cin >> a2; |
- | vec[i]=**new Derivata(a1,a2)**; | + | vec[i] = new Derivata(a1,a2); |
- | } else i--; | + | } else i--; |
- | } | + | } |
- | for (int i=0;i<n;i++) | + | for (int i = 0; i < n; i++) |
- | **vec[i]->afisare()**; | + | vec[i]->afisare(); |
- | //comportament polimorf; nu mai testez eu care e tipul si nu fac conversii explicite | + | //comportament polimorf; nu mai testez eu care e tipul si nu fac conversii explicite |
- | //Baza *b=new Derivata(1,1); | + | //Baza *b = new Derivata(1,1); |
- | // b->set_atr2(2); | + | // b->set_atr2(2); |
- | //atentie, set_atr2 nu e o functie din Baza | + | //atentie, set_atr2 nu e o functie din Baza |
- | //**ERROR:'class Baza' has no member named 'set_atr2'** | + | //ERROR:'class Baza' has no member named 'set_atr2' |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 284: | Line 283: | ||
**Recomandari** | **Recomandari** | ||
- | 1. Se recomanda sa se declare ca virtuale, functiile care, in derivari | + | -Se recomanda sa se declare ca virtuale, functiile care, in derivari ulterioare NU isi schimba semnificatia (acelasi nume, semnatura, tip returnat), ci doar li se modifica / adapteaza implementarea /comportamentul (in functie de noul tip de date). |
- | ulterioare NU isi schimba semnificatia (acelasi nume, semnatura, tip | + | -Daca o clasa are macar o functie virtuala, destructorul trebuie declarat virtual. |
- | returnat), ci doar li se modifica / adapteaza implementarea /comportamentul | + | |
- | (in functie de noul tip de date). | + | |
- | + | ||
- | 2. Daca o clasa are macar o functie virtuala, destructorul trebuie declarat | + | |
- | virtual. | + | |
</note> | </note> | ||