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