Funzioni Virtuali
Funzioni Virtuali
Lezione 15
A Cosa Servono le Funzioni Virtuali
comuni ad una gerarchia di classi la cui
implementazione varia da classe a classe
®
La funzione area() è comune a tutta la gerarchia dei
poligoni e quindi è definita in Poligono. La sua
implementazione, però, cambia da poligono a
poligono
ü Le funzioni virtuali consentono di incapsulare i
dettagli relativi alla implementazione di una
gerarchia di classi
®
Le funzioni che usano le classi della gerarchia non
devono sapere come sono derivate
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Le funzioni virtuali definiscono delle operazioni
1
Laboratorio di Algoritmi e Strutture Dati
2001-92
•1
Funzioni Virtuali
ü Ogni oggetto ha un tipo statico ed un tipo
dinamico
ü Tipo statico
®
Tipo valutato dal compilatore
ü Tipo dinamico
® Tipo valutato in esecuzione
ü In genere i due tipi coincidono
ü I tipi statico e dinamico di un puntatore od un
riferimento ad una classe derivata possono
essere diversi
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Tipo Statico e Tipo Dinamico
2
void stampa(const Poligono* pp) { pp->disegna(); }
int main() {
Quadrato q;
stampa(&q); // il riferimento alla classe derivata è
// convertito in un riferimento alla classe base
}
®
®
®
®
®
Tipo statico di &q è Poligono*
Tipo dinamico di &q è Quadrato*
Nella chiamata a stampa &q è convertito al suo tipo statico
il codice è corretto perché la funzione stampa invoca un
metodo appartenente allo scope di Poligono
In esecuzione la funzione stampa utilizza il tipo dinamico di
&q
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Uso delle Funzioni Virtuali
3
Laboratorio di Algoritmi e Strutture Dati
2001-92
•2
Funzioni Virtuali
ü Un metodo è polimorfico se
® ha differenti comportamenti (morphos) e la scelta del
comportamento corretto dipende dal contesto
ü Una funzione virtuale è polimorfica perché ha
un’unica firma ma differenti implementazioni
®
®
esiste un’unica dichiarazione della funzione area()
(nella classe Poligono), ma più implementazioni (una
per ogni classe derivata)
il programma, in esecuzione, riconosce il tipo
dinamico dell’oggetto che ha invocato area() e
chiama l’implementazione corretta di area()
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Polimorfismo e Funzioni Virtuali
4
ü Una funzione virtuale viene specificata premettendo al
suo prototipo la parola virtual
definizione della classe
all’interno della
class Poligono {
private:
virtual void area();
…
};
ü La definizione di una funzione virtuale è identica alla
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Definizione di Funzioni Virtuali
definizione di un metodo non virtuale
5
Laboratorio di Algoritmi e Strutture Dati
2001-92
•3
Funzioni Virtuali
Definizione di Funzioni Virtuali
virtuale, modificandone l’implementazione
La definizione della funzione virtuale nella classe derivata
deve avere la stessa firma della funzione ereditata
class Quadrato : public Poligono {
public:
double area();
…
};
®
double Quadrato::area() {
double _lato = _lunghezza(_vertici[0], _vertici[1]);
return _lato * _lato;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Le classi derivate possono ridefinire la funzione
6
ü Una classe base contiene tutti i metodi
comuni a tutte le sue classi derivate
®
Il metodo è virtual se la sua implementazione
dipende dal tipo della classe derivata
ü A volte non è possibile fornire definizioni
per tutti i metodi della classe base
®
Come dovrebbe essere implementato
Poligono::area()?
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Definizione Interfacce di una
Gerarchia di Classi
7
Laboratorio di Algoritmi e Strutture Dati
2001-92
•4
Funzioni Virtuali
ü Una funzione virtuale pura è una funzione che
non ha nessuna implementazione ma è comune
a tutte le classi derivate
class Poligono {
public:
virtual void area() = 0;
…
};
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Funzioni Virtuali Pure
8
ü Una classe che contiene al suo interno funzioni
virtuali pure è detta astratta
®
non è possibile definire oggetti di una classe astratta
ü Una classe derivata da una classe astratta che
definisce l’implementazione delle funzioni
virtuali pure ereditate è detta classe concreta
®
è possibile definire oggetti di una classe concreta
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Classi Astratte
9
Laboratorio di Algoritmi e Strutture Dati
2001-92
•5
Funzioni Virtuali
Implementazione di Funzioni
Virtuali
oggetto contiene una tabella delle
funzioni virtuali
®
®
tutti i puntatori alle funzioni virtuali di una classe vengono
inseriti nella tabella di funzioni virtuali
l’oggetto contiene un puntatore alla tabella delle funzioni
virtuali
ü Ogni invocazione di una funzione virtuale avviene
indirettamente tramite il puntatore alla tabella
®
Le chiamate a funzioni virtuali sono più inefficienti
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Ogni
10
AnimaleZoo
nome
alimentazione
posizione
Tabella funzioni virtuali
void disegna()
void informa();
void posizione();
AnimaleZoo();
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Implementazione di Funzioni Virtuali
11
Laboratorio di Algoritmi e Strutture Dati
2001-92
•6
Funzioni Virtuali
ü Il costruttore di una classe derivata inserisce i puntatori
delle implementazioni di funzioni virtuali definite nella
classe nella tabella delle funzioni virtuali ereditata
®
®
Il costruttore di Orso inserisce l’indirizzo dell’implementazione
di disegna() nella tabella delle funzioni virtuali ereditata da
AnimaleZoo
quando un oggetto Orso viene convertito in AnimaleZoo conserva
la sua tabella di funzioni virtuali, con gli indirizzi delle
implementazioni definite dalla classe Orso
ü la classe derivata può definire una propria tabella di
funzioni virtuali
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Implementazione Funzioni Virtuali
12
Uso delle Funzioni Virtuali
modo virtuale solo se è invocata tramite un
puntatore alla classe
ü La funzione è implementata in modo normale
se
®
®
®
è invocata tramite un oggetto della classe
è invocata usando l’operatore di visibilità
È invocata all’interno di un costruttore o
distruttore
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Una funzione virtuale viene implementata in
13
Laboratorio di Algoritmi e Strutture Dati
2001-92
•7
Funzioni Virtuali
AnimaleZoo
Estinsione
Erbivoro
Orso
Bradipo
Panda
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio: Sistema Informativo
Zoo
14
Ambiguità di Derivazioni Multiple
accadere che una classe derivi da una classe
base attraverso percorsi differenti
®
Es. la classe Panda è derivata attraverso due
percorsi da AnimaleZoo
ü Tutti gli accessi agli elementi ereditati dalla
classe base sono ambigui
®
la classe Panda contiene due copie di ognuno degli
elementi ereditati da AnimaleZoo
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Se la gerarchia di derivazione è un DAG può
15
Laboratorio di Algoritmi e Strutture Dati
2001-92
•8
Funzioni Virtuali
Derivazioni Virtuali
interno un oggetto della classe base ma solo un
puntatore ad un oggetto della classe base
®
la classe Panda contiene due puntatori allo stesso sottoggetto
AnimaleZoo ereditato sia da Orso che Bradipo
ü È sufficiente definire come virtuali solo le derivazioni
che hanno come classe base quella che sarà derivata
più volte
®
®
®
Es. le derivazioni da AnimaleZoo di Orso e Bradipo
class Orso : public virtual AnimaleZoo { … };
In generale non efficiente
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Una classe derivata virtualmente non contiene al suo
16
Derivazioni Virtuali
costruttori dei suoi membri nel seguente
ordine:
costruttore delle classi base ereditate
virtualmente
® costruttori
delle
classi
base
(che
conterranno eventualmente puntatori alla
classe ereditata virtualmente)
® costruttori dei suoi dati membro
® costruttore della classe
®
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Il costruttore di una classe chiama i
17
Laboratorio di Algoritmi e Strutture Dati
2001-92
•9