Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a. 2002-2003.

Slides:



Advertisements
Presentazioni simili
Programmazione ad oggetti
Advertisements

Funzioni Friend Come abbiamo visto non possiamo accedere a membri privati di una classe dall'esterno della classe. Ma a volte abbiamo bisogno di farlo.
Costruttori e Distruttori
Recupero debito quarto anno Primo incontro
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
1 Semantica Operazionale di un frammento di Java: lo stato.
Classi ed Oggetti in Java (Cenni). Richiami Ruolo delle Classi in Java Oggetti.
Fondamenti di Informatica
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Caratteri e stringhe di caratteri
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
1 Programmazione ad oggetti in Java E.Mumolo, DEEI
1 Lezione XIII Lu 17-Nov-2005 Programmare le classi.
Programmazione Corso di laurea in Informatica
Approfondimento delle classi
Type int_stack = struct { int top; int P[100]; } int_stack creapila() { int_stack s = new int_stack; s.top = 0; return s; } int_stack push(int_stack s,
Type int_stack = struct { int top; int P[100]; } int_stack creapila() { int_stack s = new int_stack; s.top = 0; return s; } int_stack push(int_stack s,
memoria gestita staticamente:
Lab. Calc. AA 2005/061 Classi. Lab. Calc. AA 2005/062 C e C++ Fino a questo punto abbiamo introdotto gli elementi base di qualsiasi linguaggio di programmazione,
Lab. Calc. 2005/06 Ereditarietà. Lab. Calc. 2005/06 Scopo di questa lezione: Imparare a creare nuove classi ereditando da classi già esistenti. Capire.
1 laboratorio di calcolo II AA 2003/04 quinta settimana a cura di Domizia Orestano Dipartimento di Fisica Stanza tel. ( )
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
Java base IV: Java e la programmazione O.O.
IL TEMA DELLA RIUSABILITÀ Si vuole riusare tutto ciò che può essere riusato (componenti, codice, astrazioni) Non è utile né opportuno modificare codice.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
I Metodi in Java Il termine "metodo" è sinonimo di "azione". Quindi, affinché un programma esegua qualche istruzione, deve contenere metodi.
CdL Ingegneria Elettronica, Telecomunicazioni ed Automazione Fondamenti di Informatica LB A.A /02/2008 Alessandra Toninelli
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
Enumerazioni e Classi 1. Enumerazioni Permettono di definire nuovi tipi che consistono in un insieme di valori costanti (ognuno con un nome) – Migliorano.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
Fondamenti di Programmazione Prof.ssa Elisa Tiezzi
ISTITUTO STATALE DI ISTRUZIONE SUPERIORE F. ENRIQUES CORSO JAVA – PROVA INTERMEDIA DEL 12 MARZO 2007 NOME: COGNOME: ________________________________________________________________________________.
I metodi F. Bombi Campi e metodi Abbiamo visto che una classe può contenere – Campi – Metodi stato I campi sono utilizzati per memorizzare.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Approfondimenti sulle Classi.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Polimorfismo.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Ereditarietà.
Oggetti in C# Lezione 1 Classi ed istanze Oggetti in C# - Lezione 1.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Corso di Algoritmi e Strutture Dati con Laboratorio A.A. 2014/15 Lezione 3.
Programmazione a oggetti
CORSO DI PROGRAMMAZIONE II Lezione 22
Programmazione ad oggetti
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
Fondamenti di Informatica II Ingegneria Informatica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Informatica 4 Funzioni. FUNZIONE: definizione MATEMATICA Relazione (o applicazione) binaria tra due insiemi A e B che associa a ogni elemento di A un.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 7 Tipi di dato e strutture dati Specifica e realizzazione di strutture informative come classi.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 8 Oggetti statici e dinamici. Classi annidate. Costruttori/distruttori.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
Fondamenti di Informatica 2 Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Cose nuove di Java (prima a chiacchiera, poi formalmente)
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
Progettare una classe 21 Febbraio La classe BankAccount Vogliamo realizzare una classe i cui oggetti sono dei semplici conti bancari. * Identifichiamo.
Esercitazione del 9 marzo 2007 Ereditarieta’. Richiami Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio.
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Strutture e Classi.
1 Java secondo contatto Nel tunnel una luce…. 2 Esercizio - Contatore Definire la classe Contatore con le seguenti caratteristiche:  Il metodo getValore.
Fondamenti di informatica T-A Esercitazione 3 : Classi, metodi, visibilità, metodi statici AA 2012/2013 Tutor : Domenico Di Carlo.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Introduzione alle Classi e agli Oggetti in Java 1.
Transcript della presentazione:

Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a

Classi ed Oggetti Il C++ è un linguaggio di programmazione che fornisce gli strumenti per la programmazione ad oggetti. In C++ le unità fondamentali sono le classi. Le classi implementano gli ADT. Gli oggetti sono istanze delle classi. Vengono create considerando le classi come il loro tipo base.

Classi ed Oggetti La definizione di classe avviene tramite la parola chiave class e la forma è simile alla struct, di cui rappresenta l’evoluzione: class nome_classe { public: variabili e funzioni pubbliche; private: variabili e funzioni private; protected: variabili e funzioni protette; };

Classi ed Oggetti Le variabili e funzioni definite dopo la parola chiave public e prima dell’inizio della parola chiave successiva sono accessibili da altre parti del programma. Le variabili e funzioni definite dopo la parola chiave private e prima dell’inizio della parola chiave successiva sono nascoste ad altre parti del programma e possono essere usate solo da funzioni membro della classe. Vedremo più avanti il significato della parola chiave protected. Le parole chiave protected, public e private si chiamano specificatori di accesso ai membri

Classi ed Oggetti Es: class Persona { private: int stipendio; public: char cognome[30]; char indirizzo[30]; }; Persona Ugo; // si istanzia un oggetto avente // come tipo dato la classe Persona; Altre parti del programma possono accedere a Ugo.cognome e Ugo.indirizzo ma non direttamente a Ugo.Stipendio

Classi ed Oggetti E’ possibile per altre parti del programma accedere e/o manipolare i membri protetti tramite le funzioni membro della classe. Le funzioni membro di una classe definiscono il comportamento che esibiscono gli oggetti appartenenti a quella stessa classe. In C++ implementano i metodi dell’ OOP. La classe è una evoluzione della struct di C. La differenza è che i membri senza specificatore di accesso in una classe sono privati, mentre in una struttura sono pubblici.

Classi ed Oggetti Es: class counter { public: void reset( ); void incr (); void decr ( ); int get( ); private: int val; }; funzioni membro

Classi ed Oggetti In alcuni casi, è importante avere la possibilità di definire dei membri di una classe comuni a tutti gli oggetti della stessa classe. Per fare questo, si usa il modificatore static per dichiarare una variabile statica della classe, ovvero condivisa da tutti gli oggetti della classe. Es: class counter { public: void reset( ); …. private: static int val; };

Classi ed Oggetti E’ possibile dichiarare una funzione non membro o una classe come friend di una classe. In questo modo si consente alla funzione o classe friend di accedere ai membri privati delle classe. Es; class counter { public: friend void print(int); ……...};

Classi ed Oggetti: l’operatore :: Una volta definiti i prototipi delle funzioni membro, occorre scrivere il codice delle funzioni e far riconoscere al compilatore che la funzione è un metodo di una determinata classe. Per questo si usa l’operatore di risoluzione di ambito ::. Es: void contatore::reset ( ) { val = 0;}; void contatore::incr ( ) { val++;}; void contatore::decr ( ) { val--;}; int contatore::get ( ) { return val;};

Classi ed Oggetti: l’operatore :: Tramite l’operatore di risoluzione di ambito il compilatore riconosce di quale classe la funzione membro è un metodo e distingue tra metodi aventi lo stesso nome ma appartenenti a classi differenti. Quando una funzione membro chiama una funzione che appartiene alla stessa classe, può farlo direttamente senza ricorrere all’operatore di risoluzione di ambito.

Classi ed Oggetti:dichiarazione di oggetti Una volta definita una classe, è possibile istanziare un numero qualsiasi di oggetti appartenenti alla classe. Questi oggetti saranno distinti tra loro, avranno la stessa rappresentazione e potranno usare gli stessi metodi forniti dalla classe. Es: contatore c1, c2; definisce due oggetti c1 e c2 di tipo contatore ognuno dei quali ha la propria copia di val e può eseguire solo le operazioni definite nella classe contatore.

Classi ed Oggetti: accesso ai membri Per usare i membri di un oggetto si usano l’operatore freccia e l’operatore punto con le stesse modalità usate per le struct. Es: c1.reset( ); Questa istruzione ha il significato di invio di messaggio all’oggetto c1 di eseguire l’operazione reset( ) che azzera la variabile privata val. Un oggetto può inoltre accedere al proprio indirizzo tramite un puntatore di nome this

Classi ed Oggetti: Costruttori e Distruttori Nella maggior parte dei casi occorre inizializzare alcune parti dell’oggetto prima che siano utilizzate. Il C++ consente agli oggetti di inizializzarsi al momento della loro creazione tramite i costruttori. Un costruttore è una funzioni membro pubblica di una classe che ha le seguenti caratteristiche ha lo stesso nome della classe di appartenenza non deve avere un tipo di ritorno (neanche void) può avere argomenti di default

Es: class counter { public: counter (int n=0) {val = n; }; void reset( ); void incr (); void decr ( ); int get( ); private: int val; }; Costruttore Classi ed Oggetti: Costruttori e Distruttori

I costruttori sono invocati automaticamente quando gli oggetti vengono istanziati. Es: contatore c1, c2(6); Quando viene eseguita l’istruzione sopra descritta, c1 viene creato con val = 0 (valore di default) mentre c2 viene istanziato con val = 6. Il costruttore viene invocato quando viene allocata memoria all’oggetto: contatore *p; //il costruttore non è eseguito p = new contatore(2) ; //il costruttore è eseguito

Classi ed Oggetti: Costruttori e Distruttori Se un costruttore ammette argomenti non di default, questi devono essere specificati nella dichiarazione dell’oggetto. Es. class counter { public: counter (int n, int p) {val = n; sem = p; }; … private: int val,sem}; counter c1(2,0), c2(6,3), c3(7,4);

Classi ed Oggetti: Costruttori e Distruttori Il distruttore è complementare al costruttore e viene usato ogni volta che un oggetto viene distrutto, cosa che avviene quando si esce dall’ambito dell’oggetto. Un distruttore è una funzioni membro pubblica di una classe che ha le seguenti caratteristiche ha lo stesso nome della classe di appartenenza preceduto dal carattere ~. non deve avere un tipo di ritorno (neanche void) non può avere argomenti

Es: class counter { public: counter (int n=0) {val = n; }; ~counter ( ) {cout << “contatore distrutto\n”; }; void reset( ); void incr (); void decr ( ); int get( ); private: int val; }; Distruttore Classi ed Oggetti: Costruttori e Distruttori

Un esempio della necessità di distruttore si ha quando un oggetto viene rilasciato ma non tutta la memoria occupata da esso viene rilasciata Es: class stringa { char *str; public: stringa (char *str) {str = new char[80]; }; set (char *str); show( ); }; Quando viene rilasciato un oggetto di tipo stringa, l’area di memoria creata con new non è rilasciata e non è più disponibile sull’heap!!!! Classi ed Oggetti: Costruttori e Distruttori

Modificando la classe introducendo un distruttore si ha class stringa { char *str; public: stringa (char *str) {str = new char[80]; }; ~stringa( ) {if (str != NULL) delete[ ] str; } set (char *str); show( ); }; e si risolve il problema, poiché viene rilasciata l’area di memoria heap tramite la delete[ ]. Classi ed Oggetti: Costruttori e Distruttori

Un oggetto può essere raggruppato in array Es: contatore cont[4]; Si può accedere ad un oggetto tramite puntatore. Per un oggetto vale l’aritmetica dei puntatori, l’operatore &, l’operatore di dereferenza, l’operatore punto, l’operatore freccia I reference a oggetti sono possibili come i reference a variabili si possono passare degli oggetti a funzioni come qualsiasi altra variabile e le funzioni possono restituire un oggetto Classi ed Oggetti: Costruttori e Distruttori

Vi sono comunque dei problemi: 1) quando un oggetto viene passato ad una funzione ne viene fatta una copia bit a bit che viene data al parametro della funzione. Se l’oggetto contiene un puntatore a una locazione di memoria allocata dinamicamente, allora la copia punterà alla medesima regione di memoria, ed ogni modifica si rifletterà sull’originale. L’oggetto originale ne viene pertanto influenzato. Classi ed Oggetti: Costruttori e Distruttori

Oggetto stringa in main() Copia dell’oggetto stringa nel passaggio a funzione Area di memoria per str

2) quando un funzione restituisce un oggetto, il compilatore genera automaticamente un oggetto temporaneo contenente il valore restituito alla funzione. Quando il valore viene restituito alla funzione chiamante, l’oggetto temporaneo va fuori ambito e provoca la chiamata al distruttore, che potrebbe eliminare qualcosa di necessario alla routine chiamante, come della memoria allocata dinamicamente. Classi ed Oggetti: Costruttori e Distruttori

Oggetto stringa restituito dalla funzione Oggetto temporaneo stringa contenente il valore dell’oggetto stringa restituito dalla funzione e sottoposto all’azione del distruttore Area di memoria per str

La risoluzione a questo tipo di problema è il costruttore di copia. Con il costruttore di copia, è possibile specificare con precisione cosa accade quando : un oggetto viene usato per inizializzarne un altro in un’istruzione di dichiarazione un oggetto viene passato come parametro a una funzione viene creato un oggetto temporaneo da usare come valore restituito ad una funzione Classi ed Oggetti: Costruttori e Distruttori

La forma più comune per il prototipo del costruttore di copia è la seguente: nome_classe (const nome_classe &); Es: class stringa { char *str; public: stringa(char *, int =40); //costruttore normale stringa(const stringa &,int =40); //costruttore di copia char *getcar( ){ return str;} }; Classi ed Oggetti: Costruttori e Distruttori

stringa::stringa(char *inp, int SIZE=40) { int i; str = new char[SIZE]; cout << "sono qui \n"; for(i=0; *(inp+i) != '\0';i++) str[i]=inp[i]; str[i]= '\0'; }; stringa::stringa(const stringa &ob,int SIZE=40) { int i; str = new char[SIZE]; for(i=0;ob.str[i]!='\0';i++) str[i]=ob.str[i]; str[i]='\0'; }; Classi ed Oggetti: Costruttori e Distruttori

void display(stringa ob) { for(int i=0;*(ob.getcar()+i) != '\0';i++) cout << *(ob.getcar()+i); cout << "\n"; }; main ( ) { stringa a("PIPPO25"); display(a); //viene invocato il costruttore di copia return 0; } Classi ed Oggetti: Costruttori e Distruttori

E’ possibile effettuare l’overload degli operatori del C++ in relazione ai tipi di classe. E’ possibile, per esempio, effettuare un overload dell’operatore + e fargli eseguire delle operazioni definite dal programmatore. Il concetto di overload è pertanto strettamente legato all’overloading delle funzioni. La forma generale di una funzione operatore utilizza la parola chiave operator nel seguente modo tipo nome_classe::operator op(argomenti); dove op è l’operatore di cui si vuole effettuare l’overloading. Classi ed Oggetti: Overload di operatori

Es: class parall { int x,y,z; public: parall operator=(parall); …..}; parall parall::operator=(parall ob) {parall tmp; tmp.x = ob.x; tmp.y= ob.y; tmp z = ob.z; return tmp; } Classi ed Oggetti: Overload di operatori

Es: parall a, b; ….. b=a; //viene usato l’operatore = di parall L’operatore = effettua l’overloading dell’operatore = standard in C++. Anche altri operatori (p.e. &&, ||) standard in C++ possono essere ridefiniti. Classi ed Oggetti: Overload di operatori

La composizione in C++ avviene specificando gli oggetti componenti (oggetti membro) all’interno della classe di cui fanno parte. Occorre comunque indicare gli argomenti del costruttore della classe composta da passare ai costruttori degli oggetti membro Questo avviene tramite gli inizializzatori di membro, che vengono usati nella definizione del costruttore. Classi ed Oggetti: Composizione

Es: class Data: {Data (int, int, int); …}; Impiegato::Impiegato( char *nome, int giorno, int mese, int anno) : datadinascita(int giorno, int mese, int anno) {…}; Se una classe Impiegato ha un oggetto membro datadinascita di classe Data, i parametri giorno, mese e anno saranno passati al costruttore Data Classi ed Oggetti: Composizione

Nella terminologia del C++, la superclasse si chiama classe base, mentre la sottoclasse si chiama classe derivata. Le modalità di derivazione di una classe da una classe base sono specificate tramite lo specificatore di accesso alla classe base e la forma generale per dichiarare che una classe eredita da un’altra è: class classe_derivata: accesso classe base { corpo della classe_derivata} dove accesso può essere private, public e protected Classi ed Oggetti: Ereditarietà

Es: class impiegato { public: Impiegato (char *) ; ~Impiegato( ); void print( ) const; private: char *nome;}; class interinale: public impiegato { public: ….. void print( ) const; private: double orario; double salario; }; Classi ed Oggetti: Ereditarietà

Quando una classe base viene ereditata come pubblica, tutti suoi membri pubblici diventano pubblici per la classe derivata mentre i suoi membri privati sono nascosti alla classe derivata. Quando una classe base viene ereditata come privata, tutti i suoi membri pubblici diventano membri privati della classe derivata mentre i suoi membri privati sono nascosti alla classe derivata Classi ed Oggetti: Ereditarietà

Ricordiamo che i membri di una classe possono essere private, public e protected. La modalità protected è simile alla private, con una differenza che si riscontra nel caso di classe derivata: quando una classe base viene ereditata come pubblica, tutti suoi membri protected diventano membri protetti per la classe derivata; quando una classe base viene ereditata come privata, tutti suoi membri protected diventano membri privati per la classe derivata In questo modo è possibile dar vita a membri che sono privati per la loro classe ma che sono ereditabili ed accessibili per una classe derivata. Classi ed Oggetti: Ereditarietà

Es: class base { public: void set(int) ;... protected: int i, j; // privato per base, ma accessibile per derivato }; class derivato: public base { public: … // può accedere a i e j di base private: int k; }; Classi ed Oggetti: Ereditarietà

Quando una classe base viene ereditata come protected, tutti suoi membri pubblici e protetti diventano protetti per la classe derivata mentre i suoi membri privati sono nascosti alla classe derivata. Classi ed Oggetti: Ereditarietà

Una classe derivata eredita i membri dalla classe base e pertanto, quando si istanzia un oggetto di classe derivata, il C++ chiama dapprima il costruttore della classe base e successivamente il costruttore della classe derivata. L’esecuzione dei distruttori avviene in ordine inverso: dapprima vengono eseguiti i distruttori della classe derivata e successivamente quelli della classe base. Classi ed Oggetti: Ereditarietà

Nel caso in cui i costruttori della classe base necessitino di parametri, nella dichiarazione dei costruttori delle classi derivate si utilizzano gli inizializzatori di membro : Es: Interinale::Interinale (char *nome): impiegato(nome) { …. } Classi ed Oggetti: Ereditarietà

E’ possibile che una classe erediti le proprietà di più classe basi. In questo caso, si ha la eredità multipla (multiple inheritance). In questo caso la forma generale per dichiarare una classe con multiple inheritance è class classe_derivata: accesso1 classe_base1, accesso2 classe_base2,..accesson classe_basen { corpo della classe_derivata} dove accesso1,..,accesson possono essere private, public e protected Classi ed Oggetti: Ereditarietà

Sono possibili alcune ambiguità nei casi di eredità multipla: class a {public: int i}; class b: public a {public: int j}; class c: public a {public: int k}; class d: public b, public c { int sum}; d ob; ob.i = 5; // istruzione ambigua: quale i ?? A quale i si riferisce? A quella di b o c ?? Si introduce un elemento di ambiguità. Classi ed Oggetti: Ereditarietà

Per risolvere questi tipo di ambiguità, si usano le classi base virtuali. La loro semantica è simile alle classi base non virtuali, con in aggiunta la parola chiave virtual prima delle definizione di accesso. Es: class a {public: int i}; class b: virtual public a {public: int j}; In questo modo, quando due o più oggetti sono derivati da una classe base comune, è possibile evitare che in un oggetto derivato da quegli oggetti siano presenti più copie della classe base. Classi ed Oggetti: Ereditarietà

Il polimorfismo viene implementato tramite le funzioni virtuali. Una funzione virtuale si intende una funzione che viene preceduta dalla parola chiave virtual in una classe base e poi ridefinita in una o più classi derivate. Classi ed Oggetti: Polimorfismo

Es: class a {.. public: virtual void print ( ) {cout << “prima stampa”;} }; class b: public a {.. public: void print ( ) {cout << “seconda stampa”;} }; Classi ed Oggetti: Polimorfismo

Ciascuna classe derivata può quindi avere la propria versione di funzione virtuale, pur mantenendo la medesima interfaccia. Quando una classe derivata non ridefinisce una funzione virtuale, la funzione viene impiegata nel modo in cui è definita nella classe base Classi ed Oggetti: Polimorfismo