Overloading

In programmazione, è detta overloading (o sovraccarico) la creazione di una famiglia di funzioni/subroutine aventi tutte lo stesso nome, ma che accettino un diverso insieme di argomenti (signature), e che eventualmente restituiscano un diverso valore di ritorno (in Java con signature non viene incluso il valore di ritorno). Tale famiglia di funzioni è detta in rapporto di Overloading, o sovraccaricata. Non tutti i linguaggi di programmazione consentono l'overloading.

A seconda dei casi, si può parlare di overloading di funzioni, di costruttori e di operatori.Sovraccaricare il costruttore di una classe è una pratica comune per gli sviluppatori di librerie, in quanto permette loro di fornire allo sviluppatore finale diverse modalità per istanziare inizializzando l'oggetto della classe con determinati valori iniziali.

Overloading del costruttore e dei metodi delle classi

Ecco alcuni esempi di sovraccarico di un costruttore "Persona" e un metodo "Rubrica.Inserisci", in linguaggio Visual Basic (è omessa la dichiarazione di un tipo enumerativo "Sesso" di valore "Maschio/Femmina" e di alcune implementazioni)

Class PersonaPrivate _nome As StringPrivate _cognome As StringPrivate _nascita As DatePrivate _sex As SessoPublic ReadOnly Property NomeCompleto() As StringPublic Sub New(ByVal nome As String, ByVal cognome As String, ByVal nascita As Date, ByVal sex As Sesso)    _nome = nome    _cognome = cognome    _nascita = nascita    _sex = sexEnd SubPublic Sub New(ByVal AltraPersona As Persona)    _nome = altrapersona._nome    _cognome = altrapersona._cognome    _nascita = altrapersona._nascita    _sex = altrapersona._sexEnd SubEnd ClassClass Rubrica[...]Public Overloads Sub Inserisci(ByVal Nome As String, ByVal Cognome As String)Public Overloads Sub Inserisci(ByVal Item As Persona)End Class

In questo modo è possibile inizializzare un'istanza della classe Persona sia fornendo nome e cognome come stringa che copiandoli da un'altra istanza di Persona.Il codice di cui sopra è facilmente riutilizzabile in linguaggi come C, C++, C# e Java, riscrivendo il tutto secondo la sintassi del linguaggio scelto.

Overloading degli operatori

Prendiamo in considerazione il seguente esempio C++: una classe che rappresenta i numeri complessi (sono omesse le implementazioni del file .cpp)

class Complex{private:    double _r;    double _i;public:    Complex(int r, int i);    Complex(float r, float i);    Complex(double r, double i);    Complex(Complex c);}

Vorremmo essere in grado di eseguire sui numeri complessi le stesse operazioni che eseguiamo normalmente sui numeri reali. Ad esempio, vorremmo poter eseguire il seguente codice:

Complex c,d;...if (c < d)    .......cout << c;

Tale codice solleverebbe un errore di compilazione, in quanto il compilatore non è in grado di valutare da solo se il complesso c è minore di d, né tantomeno di scriverlo a video. La soluzione, adottabile solo in C++ e C#, è quella di definire un opportuno sovraccarico per gli operatori < e <<. Per fare ciò è necessario conoscere come il compilatore dei linguaggi C tratta le espressioni con operatore. Esso le traduce con una chiamata a subroutine operator?(), dove al posto di ? va il simbolo dell'operatore. Ecco quindi i prototipi (e un paio di realizzazioni) di una completa famiglia di overloading per gli operatori principali di confronto e output.

//operator<int operator<(Complex a, Complex b){    return ((a.r*a.r+a.i*a.i)<(b.r*b.r+b.i*b.i));}int operator<(Complex a, double b){    return ((a.r*a.r+a.i*a.i)<(b*b));}int operator<(Complex a, float b);int operator<(Complex a, int b);int operator<(double a, Complex b);int operator<(float a, Complex b);int operator<(int a, Complex b); //operator>int operator>(Complex a, Complex b){   return ((a.r*a.r+a.i*a.i)>(b.r*b.r+b.i*b.i));}int operator>(Complex a, double b){    return ((a.r*a.r+a.i*a.i)>b*b);}int operator>(Complex a, float b);int operator>(Complex a, int b);int operator>(double a, Complex b);int operator>(float a, Complex b);int operator>(int a, Complex b);//operator<<ostream& operator<<(ostream& out, Complex c){    cout << c.r;    if (c.i > 0)        cout << "+";    cout << c.i << "i";}

In linguaggio Visual Basic è possibile simulare il sovraccarico degli operatori implementando l'interfaccia IComparable.

Note sull'overloading

Un errore comune di molti programmatori è quello di voler creare due funzioni che accettano gli stessi tipi di parametri in ingresso e restituiscono un tipo differente. Ciò non è possibile perché l'esecutore identifica le funzioni e le subroutine, a livello assembly, mediante delle etichette (label). Tali label rispecchiano la signature della funzione stessa, e pertanto due label uguali non possono coesistere all'interno di uno stesso spazio di visibilità. È comunque possibile definire due o più funzioni dalla stessa signature all'interno di spazi di nomi diversi senza ottenere errori di compilazione.

L'overloading, infine, non influisce sulla corretta esecuzione delle procedure ricorsive.

Voci correlate

Collegamenti esterni

Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica