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