Overloading: differenze tra le versioni

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca
Contenuto cancellato Contenuto aggiunto
Alfio (discussione | contributi)
→‎Overloading degli operatori: tolto il C (non ha l'overloading degli operatori)
Alfio (discussione | contributi)
mNessun oggetto della modifica
Riga 1: Riga 1:
In Programmazione, si dice '''Overloading''' una famiglia di [[funzione|fuzioni]]/[[subroutine]] avente lo stesso nome, ma con la possibilità di accettare un diverso set di argomenti ([[signature]]), ed eventualmente restituire un diverso [[valore di ritorno]]. Tale famiglia di funzioni è detta ''in rapporto di Overloading'', o ''sovraccaricata''.
In orogrammazione, si dice '''overloading''' una famiglia di [[funzione|fuzioni]]/[[subroutine]] avente lo stesso nome, ma con la possibilità di accettare un diverso set di argomenti ([[signature]]), ed eventualmente restituire un diverso [[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 [[costruttore|costruttori]] e di [[operatore|operatori]].
A seconda dei casi, si può parlare di overloading di funzioni, di [[costruttore|costruttori]] e di [[operatore|operatori]].
Riga 103: Riga 103:
In linguaggio [[Visual Basic]] è possibile simulare il sovraccarico degli operatori implementando l'interfaccia IComparable.
In linguaggio [[Visual Basic]] è possibile simulare il sovraccarico degli operatori implementando l'interfaccia IComparable.


==Note sull'Overloading==
==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 [[funzione|funzioni]]/[[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 [[namespace|spazi di nomi]] diversi senza ottenere errori di compilazione.
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 [[funzione|funzioni]]/[[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 [[namespace|spazi di nomi]] diversi senza ottenere errori di compilazione.


L'Overloading, infine, non influisce sulla corretta esecuzione delle procedure [[Algoritmo ricorsivo|ricorsive]].
L'overloading, infine, non influisce sulla corretta esecuzione delle procedure [[Algoritmo ricorsivo|ricorsive]].


[[Categoria: Linguaggi di programmazione]]
[[Categoria: Linguaggi di programmazione]]

Versione delle 17:48, 29 ago 2005

In orogrammazione, si dice overloading una famiglia di fuzioni/subroutine avente lo stesso nome, ma con la possibilità di accettare un diverso set di argomenti (signature), ed eventualmente restituire un diverso 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 inizializzare la 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
     _sesso = altrapersona.sesso
 End Sub
 End Class


 Class Rubrica
 [...]
 Public Overloads Sub Inserisci(ByVal Nome As Stirng, 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 manualmente i dati che copiandoli da un'altra istanza di Persona. Allo stesso modo possiamo inserire in rubrica il nome e cognome manualmente oppure prenderli da un oggetto 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);
 }
 

A prescindere dal sovraccarico del costruttore, utile a inizializzare l'oggetto con più tipi di valori, e dalla mancanza di proprietà pubbliche per ottenere/impostare il valore del numero, ci si pone il problema del confronto. Un codice del tipo

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

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 di una completa famiglia di overloading per gli operatori principali di confronto e output. NOTA: è richiesto l'utilizzo della libreria Math

 //operator<
 int operator<(Complex a, Complex b) {
       return (sqrt(a.r*a.r+a.i*a.i)<sqrt(b.r*b.r+b.i*b.i));
 }
 int operator<(Complex a, double b) {
       return (sqrt(a.r*a.r+a.i*a.i)<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 (sqrt(a.r*a.r+a.i*a.i)>sqrt(b.r*b.r+b.i*b.i));
 }
 int operator>(Complex a, double b) {
       return (sqrt(a.r*a.r+a.i*a.i)>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/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.