Osservazioni generali

In C, la proliferazione di funzioni con nome diverso ma che svolgono compiti semanticamente equivalenti (con lievi differenze, e.g. tipo dei parametri) è dovuto al fatto che i nomi devono essere unici nello scope di esistenza.

L’attività di programmazione deve gestire i problemi legati all’esistenza di numerose funzioni “uguali” ma con nomi diversi (es. le funzioni di I/O).

Un esempio tra tutti: l’uso di una versione sbagliata della funzione che si ha in mente.

L’uso del C come linguaggio non tipizzato (es: “…”) è causa di errori in esecuzione legati ad un uso improprio di funzioni.

Il C++ permette di effettuare il cosiddetto overloading di funzioni e operatori.

L’overloading consiste nella pratica di fornire più di una definizione per un dato nome (funzione o operatore) in uno stesso scope.

E’ compito del compilatore scegliere la versione opportuna della funzione (o dell’operatore) basandosi sugli argomenti presenti nella chiamata.

Overloading di funzioni

L’overloading può essere considerato una comodità notazionale per ridurre il numero dei nomi utilizzati. E’ particolarmente utile nei casi di funzioni quali sqrt, print, open, ...

A fronte di una chiamata di funzione pippo il compilatore confronta i tipi dei parametri attuali con i tipi dei parametri formali di tutte le funzioni con nome pippo, associando la versione con i parametri che corrispondono (o generando un errore di compilazione in caso di mancata corrispondenza).

L’overloading richiede che funzioni con lo stesso nome si differenzino secondo opportune regole. Le principali sono:

  1. Le funzioni non possono differenziarsi solamente per il tipo di valore di ritorno
  2. Per ogni tipo T, parametri di tipo T e T& vengono considerati differenti ma possono dare problemi di ambiguità nelle chiamate
  3. Puntatori e vettori di uno stesso tipo sono considerati uguali.
void print(double);
void print(long); //ok
int f(int);
int f(int & ); //tollerato ma attenzione all’ambiguità
void f(char * );
void f(char v[]); //errore
int h(int);
int h(const int); //errore
float h(int); //errore

Corrispondenza degli argomenti

Una chiamata ad una funzione f viene risolta cercando (nello scope corrente) tra tutte le funzioni con nome f quella i cui parametri formali corrispondono esattamente ai parametri attuali forniti nella chiamata. Al fine della corrispondenza tra parametri si considerano:

  1. conversioni standard al tipo del parametro formale