Overloading
![Niente fonti!](http://upload.wikimedia.org/wikipedia/commons/thumb/6/64/Question_book-4.svg/45px-Question_book-4.svg.png)
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 Persona Private _nome As String Private _cognome As String Private _nascita As Date Private _sex As Sesso Public ReadOnly Property NomeCompleto() As String Public 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 = sex End Sub Public Sub New(ByVal AltraPersona As Persona) _nome = altrapersona._nome _cognome = altrapersona._cognome _nascita = altrapersona._nascita _sex = altrapersona._sex End Sub End Class Class 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
- Overriding
- Polimorfismo (informatica)
- Programmazione a oggetti
Collegamenti esterni
- Mauro Cappelli, overloading, in Enciclopedia della scienza e della tecnica, Istituto dell'Enciclopedia Italiana, 2007-2008.
- (EN) Denis Howe, overloading, in Free On-line Dictionary of Computing. Disponibile con licenza GFDL
![](http://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Computer_n_screen.svg/24px-Computer_n_screen.svg.png)