Lezione 7
Sovrapposizione di Funzioni
Sovrapposizione di Funzioni
Lezione 7
ü La sovrapposizione (overloading) è un meccanismo che
consente di assegnare ad un nome significati differenti
®
ü La
Quando il nome viene utilizzato in una frase il significato
corretto viene specificato dal contesto
sovrapposizione
linguaggi naturali
®
è
utilizzata
ampiamente
nei
Es. conti (titolo nobiliare e sequenza di calcoli aritmetici)
ü Per evitare situazioni di ambiguità il contesto della frase
deve chiarire il corretto significato da dare al nome
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Sovrapposizione di un Nome
1
Laboratorio di Algoritmi e Strutture Dati
2001/02
1
Lezione 7
Sovrapposizione di Funzioni
ü Il C++ contiene diversi esempi di “parole” che
hanno significati sovrapposti
®
®
gli operatori +, -, *, / etc. etc. (dipende dagli operandi)
i nomi delle variabili (dipendono dal campo di
visibilità)
ü Il contesto dell’espressione in cui compare
l'identificatore chiarisce il suo significato
®
altrimenti il compilatore segnala un errore di
ambiguità
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Sovrapposizione di Identificatori
2
ü Il C++ consente di sovrapporre il nome di una funzione
®
il programma contiene più funzioni che hanno lo stesso nome
ma comportamenti differenti
ü Le varie versioni della funzione devono avere firme
differenti
®
la firma di una funzione è costituita dal nome della funzione e
dal tipo dei suoi parametri
ü Tutte le versioni sovrapposte della funzione devono
essere definite nello stesso scope
ü La risoluzione dell’overloading di funzioni è uno degli
aspetti più complessi del C++
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Sovrapposizione di Funzioni
3
Laboratorio di Algoritmi e Strutture Dati
2001/02
2
Lezione 7
Sovrapposizione di Funzioni
Perché Sovrapporre Funzioni
definire un gruppo di funzioni differenti che svolgono
la stessa operazione logica
int max(int, int); // massimo tra due interi
int max(int*, int); // massimo in un vettore di interi
int max(Lista&); // massimo in una lista di interi
ü La scelta della versione corretta della funzione è
effettuata dal compilatore sulla base degli argomenti
della chiamata a funzione
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Sovrapporre il nome di una funzione consente di
4
Perché Sovrapporre Funzioni
logica implementata dalla funzione
ü In C tutte le funzioni devono avere nomi distinti
®
il nome della funzione non può corrispondere all’operazione
logica implementata
ü La
sovrapposizione
fornisce
soltanto
una
semplificazione lessicale, consentendo di assegnare un
unico nome ad ogni operazione logica
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü In C++ il nome della funzione individua l’operazione
5
Laboratorio di Algoritmi e Strutture Dati
2001/02
3
Lezione 7
Sovrapposizione di Funzioni
ü Evitare di sovrapporre quando l'identificazione di più
funzioni con un unico nome fa perdere informazioni
Video& muoviOrigine();
Video& muoviX(int);
Video& muoviY(int);
Video& muovi(int, int);
ü Spesso si può evitare di ricorrere alla sovrapposizione
utilizzando l’inizializzazione per default dei parametri
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Quando non Sovrapporre
6
Sovrapposizione di Funzioni
come
®
redichiarazioni se la firma ed il tipo del risultato delle due
dichiarazioni coincidono
extern void stampa(int* ia, int dim);
void stampa(int *array, int size);
® un errore se le firme coincidono ma i tipi dei risultati sono
differenti
unsigned int massimo(int* ia, int dim);
int massimo(int *array, int size);
® dichiarazioni sovrapposte se le due firme sono distinte
int media(int* array, int size);
double media(double a, double b);
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Due dichiarazioni di una funzione sono considerate
7
Laboratorio di Algoritmi e Strutture Dati
2001/02
4
Lezione 7
Sovrapposizione di Funzioni
ü Due dichiarazioni della stessa funzione che differiscono
solo per alcuni parametri inizializzati per default non
sono funzioni sovrapposte
extern void stampa(int* ia, int dim);
void stampa(int *array, int size = 10);
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Sovrapposizione e Inizializzazione
per Default
8
ü Due parametri passati per valore che differiscono per il
qualificatore const sono considerati uguali
void f(int);
void f(const int);
// ridichiarazione di f()
ü Due
parametri passati per riferimento che
differiscono per il qualificatore const sono considerati
differenti
void f(int&);
void f(const int&);
// funzione sovrapposta
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Sovrapposizione e Parametri
Costanti
9
Laboratorio di Algoritmi e Strutture Dati
2001/02
5
Lezione 7
Sovrapposizione di Funzioni
ü Tutte le funzioni di un insieme di funzioni sovrapposte
devono essere dichiarate nello stesso scope
void stampa(const string&);
void stampa(double); // funzione sovrapposta
ü Una funzione definita in uno scope locale nasconde le
funzioni definite negli scope esterni e non è visibile al
di fuori del suo scope
namespace ASD {
void stampa(int);
// nasconde le due funzioni globali
void f() { stampa(“ciao”); } // ERRORE
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Sovrapposizione e Scope
10
Sovrapposizione e Namespace
funzioni di un namespace X visibili in un
namespace Y
®
®
queste funzioni si sovrappongono a quelle definite in
Y
si può rendere visibile solo il nome del gruppo di
funzioni sovrapposte
namespace Lib {
int max(int, int);
int max(double, double);
}
using Lib::max;
using Lib::max(int, int);
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Le dichiarazioni using possono rendere delle
// ERRORE
11
Laboratorio di Algoritmi e Strutture Dati
2001/02
6
Lezione 7
Sovrapposizione di Funzioni
Sovrapposizione e Namespace
di un namespace al namespace corrente
®
queste funzioni si sovrappongono a quelle definite nel
namespace corrente
namespace Lib {
int max(int, int);
int max(double, double);
}
extern int max(int *, int);
using Lib::max;
void funzione() {
max(23, 44);
// chiama int max(int, int);
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Le dichiarazioni using aggiungono tutti i membri
12
ü Le direttive using aggiungono tutti i membri di
un namespace al campo di azione A (scope) in
cui il namespace è stato definito
®
queste funzioni si sovrappongono a quelle definite nel
campo di azione A
ü E' possibile sovrapporre anche funzioni C,
definite in linkage directive
®
®
la linkage directive viene applicata dopo aver risolto il
nome
nell'insieme delle funzioni sovrapposte ci può stare
una sola funzione C
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Sovrapposizione e Namespace
13
7
Lezione 7
Sovrapposizione di Funzioni
Implementazione della
Sovrapposizione
meccanismo di mangling dei nomi di funzioni
ü Ad ogni funzione del programma il compilatore
assegna un nome interno, che dipende dalla firma della
funzione
®
l’algoritmo di mangling dipende dal compilatore
int massimo(int, int);
// in g++ diventa massimo_I_I(int, int);
ü Poiché tutte le firme delle funzioni sovrapposte
devono essere differenti tutte le funzioni
programma hanno nomi interni distinti
del
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü La sovrapposizione delle funzioni è gestita attraverso il
14
ü La risoluzione di una chiamata ad una funzione
sovrapposta avviene, in maniera trasparente
all’utente,
®
Si passa attraverso un processo di corrispondenza tra
gli argomenti della chiamata ed i parametri della
funzione (argument matching)
ü Il compilatore confronta gli argomenti della
chiamata con le firme delle varie definizioni e, se
possibile, ne invoca una
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione della Chiamata ad
una Funzione Sovrapposta
15
Laboratorio di Algoritmi e Strutture Dati
2001/02
8
Lezione 7
Sovrapposizione di Funzioni
La risoluzione avviene in tre passi
1. identificazione delle funzioni candidate
funzioni che hanno lo stesso nome della funzione
chiamata
2. scelta delle funzioni utilizzabili
funzioni per cui gli argomenti della chiamata
corrispondono ai parametri per numero e tipo
3. scelta della migliore funzione utilizzabile
funzione per cui gli argomenti della chiamata
corrispondono meglio ai parametri
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Risoluzione della Chiamata ad
una Funzione Sovrapposta
16
ü Se non c'è nessuna funzione utilizzabile
® il compilatore segnala un errore di funzione non
definita
ü Se non c'è una migliore funzione utilizzabile
® il compilatore segnala un errore di ambiguità
ü Se esiste un'unica migliore funzione utilizzabile
® il compilatore risolve la chiamata passando il
controllo alla migliore funzione utilizzabile
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esiti della Chiamata ad una
Funzione
17
Laboratorio di Algoritmi e Strutture Dati
2001/02
9
Lezione 7
Sovrapposizione di Funzioni
1) void f();
2) void f(int);
3) void f(double, double =3.14);
4) void f(char*, char*);
f(5.6);
// funzioni candidate 1, 2, 3, 4
// funzioni utilizzabili 2, 3
// miglior funzione utilizzabile 3 */
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio
18
ü Per individuare la migliore funzione utilizzabile
il compilatore identifica il tipo di conversione che
deve essere applicata ad ogni argomento per
farlo corrispondere al parametro
ü Per ogni argomento si può avere
®
®
corrispondenza esatta (non serve conversione)
corrispondenza tramite conversione
w promozione
w conversione standard
w conversione definita dall'utente
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Conversioni degli Argomenti
19
Laboratorio di Algoritmi e Strutture Dati
2001/02
10
Lezione 7
Sovrapposizione di Funzioni
Il tipo dell'argomento è identico al tipo del parametro
int max(int, int);
double max(double, double);
max(10, 27);
max(3.14, 6.66);
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Corrispondenza Esatta
20
Corrispondenza Esatta
®
®
®
®
conversioni array -> puntatore
conversioni funzione -> puntatore
conversioni Lvalue -> Rvalue
conversioni di qualificazione (solo per puntatori a costante)
int a[4];
bool is_equal(const int*, const int*);
void f(int *p) {
if(is_equal(p, a) { …}
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
ü Sono corrispondenze esatte anche
21
Laboratorio di Algoritmi e Strutture Dati
2001/02
11
Lezione 7
Sovrapposizione di Funzioni
ü Un Lvalue rappresenta un oggetto che può essere
indirizzato
ü Un Rvalue è un valore che non può essere indirizzato
®
®
il valore di un'espressione
una variabile temporanea
ü La funzione si aspetta Rvalue come argomenti per i
parametri passati per valore
®
se gli argomenti sono nomi di variabili (Lvalue) devono essere
convertiti a Rvalue
ü La funzione si aspetta Lvalue come argomenti per i
parametri passati per riferimento
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Conversioni Lvalue -> Rvalue
22
#include<string>
string color(“rosso”);
void print(string);
int main() {
int a,b,c;
c=a+b;
// L’operatore + richiede una conversione da
// Lvalue in Rvalue
print(color);
// corrispondenza esatta: conv. da Lvalue in Rvalue
return 0;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio di conversioni Lvalue →
Rvalue
23
Laboratorio di Algoritmi e Strutture Dati
2001/02
12
Lezione 7
Sovrapposizione di Funzioni
1) void f(const char*);
2) void f(char*);
3) void f(bool);
const char* cp;
f(cp);
f(0);
f("ciao");
f(true);
f(static_cast<char *>(cp));
// corrisponde ad 1
// ambigua
// corrisponde a 2
// corrisponde a 3
// corrisponde a 2
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempi Corrispondenza Esatta
24
ü Riguarda solo i puntatori
ü Si tratta di una conversione che aggiunge il qualificatore
const oppure volatile al tipo puntato
int *a, *b;
bool is_equal(const int *, int *);
int main() {
if(is_equal(a, b)) cout << “true”;
else cout << “false”;
} // cosa stampa?
// true perché effettua una conversione di qualificazione
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Conversione di qualificazione
25
Laboratorio di Algoritmi e Strutture Dati
2001/02
13
Lezione 7
Sovrapposizione di Funzioni
ü Le conversioni
® Lvalue → Rvalue
® array → puntatore
® funzione → puntatore
sono chiamate trasformazioni di Lvalue
ü Una corrispondenza esatta che richiede
una
trasformazione
di
Lvalue
è
considerata migliore di una che richiede
una conversione di qualificazione
Laboratorio di Algoritmi e Strutture Dati 2001
-02
“Graduatoria” di corrispondenze esatte
26
void f(const int *);
void f(int *);
int main() {
int p[10];
const int *cpi;
f(p);
// chiama void f(int *) da array a puntatore
f(cpi); // chiama void f(const int *)
return 0;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio
27
Laboratorio di Algoritmi e Strutture Dati
2001/02
14
Lezione 7
Sovrapposizione di Funzioni
ü Se il tipo dell'argomento non corrisponde
esattamente al tipo del parametro, allora lo si
promuove
®
®
®
®
gli argomenti char, unsigned char e short vengono
promossi ad int
Un argomento unsigned short viene promosso ad
int oppure a unsigned int
gli argomenti float vengono promossi a double
gli argomenti enumerazione vengono promossi al
più piccolo tipo integrale che può contenere i
valori di tutti gli enumeratori
w Nell’ordine: int, unsigned int , long, unsigned long
®
Gli argomenti boolean vengono promossi a int
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Corrispondenza per Promozione
28
enum
colore { bianco = 100, nero = 1000, viola = 0xFFFFFFFF};
1) void f(unsigned int);
2) void f(int);
3) void f(char);
f(u'a');
f(0);
f(true);
f(viola);
// corrisponde a 2
// corrisponde a 2
// corrisponde a 2
// corrisponde a 1
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempi Corrispondenza per
Promozione
29
Laboratorio di Algoritmi e Strutture Dati
2001/02
15
Lezione 7
Sovrapposizione di Funzioni
ü Se il tipo dell'argomento non corrisponde al tipo del
parametro, né esattamente né per promozione, allora si
applicano le regole di conversone standard
® Conversioni intere
w ogni argomento di tipo integrale o enumerazione è convertito
in un altro tipo integrale
®
Conversioni in virgola mobile
w ogni argomento di tipo floating è convertito in un altro tipo
floating
®
Conversione virgola mobile-intero
w ogni tipo integrale è convertito ad un tipo floating e viceversa
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Corrispondenza per Conversione Standard
30
®
®
Conversione di puntatori
w 0 è convertito in un tipo puntatore
w ogni tipo puntatore è convertito a void*
Conversioni booleane
w Ogni argomento di tipo intero, tipo in virgola
mobile, enumeratore o puntatore è convertito al
tipo bool
Tutte le regole di conversione hanno lo stesso livello
di precedenza
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Corrispondenza per Conversione Standard
31
Laboratorio di Algoritmi e Strutture Dati
2001/02
16
Lezione 7
Sovrapposizione di Funzioni
1) void f(unsigned int);
2) void f(float);
3) void f(void*);
char *cp;
f('a');
f(0);
f(3.14);
f(cp);
// ambigua, corrisponde a 1 e 2
// ambigua , corrisponde a 1, 2, e 3
// ambigua, corrisponde a 1 e 2
// corrisponde a 3
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempi: Corrispondenza per Conversione
32
ü Nel passaggio per riferimento l'argomento della
funzione viene utilizzato per inizializzare il
corrispondente parametro riferimento
®
®
®
l'argomento deve essere dello stesso tipo del
parametro
nessuna conversione applicata
l'argomento non può essere una variabile
temporanea
ü Se il parametro è definito come riferimento
costante l'argomento può essere anche di tipo
diverso
Laboratorio di Algoritmi e Strutture Dati
2001/02
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Conversioni per Parametri di tipo
Riferimento
33
17
Lezione 7
Sovrapposizione di Funzioni
ü Una funzione è candidata se ha lo stesso nome
della funzione invocata e
la sua dichiarazione è visibile nel punto della chiamata
® la sua dichiarazione appartiene ad uno dei namespace
degli argomenti
namespace LASD {
class Matrice { … };
void f(Matrice&);
}
®
LASD::Matrice M;
f(M); // void f(Matrice&) è una funzione candidata
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Calcolo delle Funzioni Candidate
34
ü Una funzione candidata è utilizzabile se i suoi parametri
corrispondono per numero e tipo agli argomenti della
chiamata
®
oppure differiscono solo per parametri inizializzati per default
void f();
void f(int);
void f(double, double = 3.14);
f(3.12)
// funzioni utilizzabili: void f(int)
//
void f(double, double = 3.14)
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Calcolo Funzioni Utilizzabili
35
Laboratorio di Algoritmi e Strutture Dati
2001/02
18
Lezione 7
Sovrapposizione di Funzioni
ü Per ogni funzione utilizzabile il compilatore calcola il
tipo di corrispondenza tra parametri ed argomenti
ü Per ogni coppia parametro-argomento viene valutato il
tipo della sequenza di conversioni
®
il tipo della sequenza è dato dal tipo della conversione peggiore
contenuta nella sequenza
ü La migliore funzione utilizzabile deve avere
®
®
su ogni argomento una conversione non peggiore di quella di
qualunque altra funzione utilizzabile
su almeno un argomento una corrispondenza migliore di tutte
le altre funzioni utilizzabili
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Calcolo della Migliore Funzione
Utilizzabile
36
int arr[3];
void PutValues(const int *);
int main() {
//….
PutValues(arr); // 2 conversioni
// 1) da array a puntatore
// 2) conversione di qualificazione
return 0;
}
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempio di sequenza di conversioni
37
Laboratorio di Algoritmi e Strutture Dati
2001/02
19
Lezione 7
Sovrapposizione di Funzioni
ü Una
sequenza
di
conversioni
è
potenzialmente composta dalle seguenti
conversioni, nell’ordine indicato:
®
Trasformazioni di Lvalue
®
Promozioni o conversioni standard
®
Conversioni di qualificazione
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Possibile sequenza di conversioni
38
ü Per ogni coppia argomento-parametro assegna
® 1 per una corrispondenza esatta
® 2 per una corrispondenza per promozione
® 3 per una corrispondenza per conversione
® 4 per una corrispondenza definita dall'utente
ü (i1, i2, …, in) < (j1, j2, …, j n) se esiste un k tale che
i < jk
® k
i ≤ jh ∀ h ≠ k
® h
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Calcolo della Migliore Funzione
Utilizzabile
39
Laboratorio di Algoritmi e Strutture Dati
2001/02
20
Lezione 7
Sovrapposizione di Funzioni
1) void f(char*, int);
2) void f(int, int=0);
3) void f(unsigned int, double);
4) void f(char);
f(0, 'a');
f(0, 3.14);
f('a', 'b');
f(13u);
// corrisponde a 2
// ambigua
// corrisponde a 2
// ambigua
Laboratorio di Algoritmi e Strutture Dati 2001
-02
Esempi Corrispondenza con più
Parametri
40
Laboratorio di Algoritmi e Strutture Dati
2001/02
21