Funzioni Virtuali
A Cosa Servono le Funzioni Virtuali
Funzioni Virtuali
comuni ad una gerarchia di classi la cui
implementazione varia da classe a classe
®
Lezione 15
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
®
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
®
®
®
®
®
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
2
3
Definizione di Funzioni Virtuali
ü Un metodo è polimorfico se
ü Una funzione virtuale viene specificata premettendo al
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
Laboratorio di Algoritmi e Strutture Dati
2001-92
Laboratorio di Algoritmi e Strutture Dati 2001-02
dinamico
ü Tipo statico
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
}
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
definizione di un metodo non virtuale
Laboratorio di Algoritmi e Strutture Dati 2001-02
ü Ogni oggetto ha un tipo statico ed un tipo
Uso delle Funzioni Virtuali
Laboratorio di Algoritmi e Strutture Dati 2001-02
Tipo Statico e Tipo Dinamico
5
•1
Funzioni Virtuali
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;
}
ü 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()?
6
7
Classi Astratte
ü Una funzione virtuale pura è una funzione che
ü Una classe che contiene al suo interno funzioni
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
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
8
Implementazione di Funzioni
Virtuali
Laboratorio di Algoritmi e Strutture Dati 2001-02
virtuale, modificandone l’implementazione
Laboratorio di Algoritmi e Strutture Dati 2001-02
ü Le classi derivate possono ridefinire la funzione
Laboratorio di Algoritmi e Strutture Dati 2001-02
Definizione Interfacce di una
Gerarchia di Classi
Definizione di Funzioni Virtuali
9
Implementazione di 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
10
Laboratorio di Algoritmi e Strutture Dati
2001-92
AnimaleZoo
nome
alimentazione
posizione
Tabella funzioni virtuali
void disegna()
void informa();
void posizione();
AnimaleZoo();
Laboratorio di Algoritmi e Strutture Dati 2001-02
funzioni virtuali
Laboratorio di Algoritmi e Strutture Dati 2001-02
ü Ogni oggetto contiene una tabella delle
11
•2
Funzioni Virtuali
Uso delle Funzioni Virtuali
Implementazione Funzioni Virtuali
®
®
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
ü Una funzione virtuale viene implementata in
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
12
Esempio: Sistema Informativo
Zoo
Laboratorio di Algoritmi e Strutture Dati 2001-02
delle implementazioni di funzioni virtuali definite nella
classe nella tabella delle funzioni virtuali ereditata
Laboratorio di Algoritmi e Strutture Dati 2001-02
ü Il costruttore di una classe derivata inserisce i puntatori
13
Ambiguità di Derivazioni Multiple
Orso
Bradipo
Panda
®
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
14
Derivazioni Virtuali
ü Il costruttore di una classe chiama i
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
®
15
Derivazioni Virtuali
ü Una classe derivata virtualmente non contiene al suo
interno un oggetto della classe base ma solo un
puntatore ad un oggetto della classe base
Laboratorio di Algoritmi e Strutture Dati 2001-02
Erbivoro
accadere che una classe derivi da una classe
base attraverso percorsi differenti
16
Laboratorio di Algoritmi e Strutture Dati
2001-92
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
Estinsione
Laboratorio di Algoritmi e Strutture Dati 2001-02
ü Se la gerarchia di derivazione è un DAG può
AnimaleZoo
17
•3