Overloading: differenze tra le versioni

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca
Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica
+F
Riga 1: Riga 1:
{{F|informatica|febbraio 2013}}
In [[programmazione]], si dice '''overloading''' una famiglia di [[Funzione (informatica)|funzioni/subroutine]] aventi lo stesso nome, ma con la possibilità di accettare un diverso set di argomenti ([[segnatura|signature]]), ed eventualmente restituire un diverso [[valore di ritorno]] (in [[linguaggio Java|Java]] con signature non viene incluso il valore di ritorno). Tale famiglia di funzioni è detta ''in rapporto di Overloading'', o ''sovraccaricata''.
In [[programmazione]], si dice '''overloading''' una famiglia di [[Funzione (informatica)|funzioni/subroutine]] aventi lo stesso nome, ma con la possibilità di accettare un diverso set di argomenti ([[segnatura|signature]]), ed eventualmente restituire un diverso [[valore di ritorno]] (in [[linguaggio Java|Java]] con signature non viene incluso il valore di ritorno). Tale famiglia di funzioni è detta ''in rapporto di Overloading'', o ''sovraccaricata''.



Versione delle 23:48, 26 feb 2013

In programmazione, si dice overloading una famiglia di funzioni/subroutine aventi lo stesso nome, ma con la possibilità di accettare un diverso set di argomenti (signature), ed eventualmente restituire 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.

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 Overloads 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 Overloads 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