/* Pensate a come risolvere questo problema: dobbiamo sommare 3 coppie di * variabili di 3 tipi diversi: int,long,float. In C occorre scriversi 3 * funzioni di somma, una per gli int, una per i long, e una per i float: * * int sommainteri(int a,int b) {...} * long sommalong(long c,long d) {...} * float sommafloat(float e,float f) {...} * * In seguito, nel programma, dobbiamo stare attenti ad usare la funzione * giusta a seconda del tipo da sommare: * * bau = sommafloat(miofloat1,miofloat2); * beu = sommalong(miolong1,miolong2); * bou = sommaint(mioint1,mioint2); * * Se poi le mie variabili si chiamano sbirulino, scarrafone, ecc., dovro' * anche andarmi a cercare ogni volta nel listato la dichiarazione per * ricordarmi il loro tipo, per usare la funzione giusta. * In C++, invece, grazie al polimorfismo, possiamo sovrapporre metodi * aventi lo stesso nome, purche' abbiano parametri diversi: in questo * modo, possiamo riscrivere i 3 metodi visti prima dandogli lo stesso nome: * * int somma(int a,int b) {...} * long somma(long c,long d) {...} * float somma(float a,float b) {...} * * Questa sovrapposizione (overloading), ci permette ora di scrivere in * modo molto piu' semplice il listato, usando somma() per tutti i casi: * * bau = somma(miofloat1,miofloat2); * beu = somma(miolong1,miolong2); * bou = somma(mioint1,mioint2); * * Questo approccio e' migliore dal punto di vista logico, infatti quando * programmiamo e sommiamo la variabile X con la variabile Y, spesso non * ci ricordiamo il tipo di queste ultime, non essendo fondamentale, ma * se dobbiamo usare funzioni diverse a seconda del tipo, allora siamo * costretti a far entrare nel nostro ragionamento anche questo, facendoci * distrarre. Se dovessimo usare degli operatori diversi a seconda del * tipo di numeri anche quando facciamo i conti a mente, ad esempio dovessimo * pensare: "1 piuintero 1 = 2", "1.00 piufloat 1.00 = 2.00", "1 menointero * 1 = 0", "1.00 menofloat 1.00 = 0.00", "1 perintero 1 = 1", "1.00 perfloat * 1.00 = 1.00", "1 divisointero 1 = 1", "1.00 divisofloat 1.00 = 1.00", * allora fare i conti della spesa diventerebbe difficile anche per un * professore di matematica. * Invece, grazie al polimorfismo, si puo' "scaricare" questo compito al * compilatore, lasciando a noi i problemi piu' seri. * Da notare che il tipo di valore restituito dal metodo (ritorno) non * conta quando il compilatore deve scegliere che overload chiamare: per * tale scopo sono presi in considerazione solo i parametri in entrata. * * Vediamo questo esempio: */ #include <iostream.h> // Header necessario per usare CIN e COUT // Questo e' un commento C++ ad una sola linea /* Ecco i 3 metodi aventi lo stesso nome e parametri diversi, che grazie * al polimosfismo si overloadano (soprappongono): ogni volta verra' * chiamato automaticamente il metodo giusto a seconda del tipo. */ int somma(int a,int b) { return(a+b); } // Ora la versione per i long long somma(long c,long d) { return(c+d); } // Infine la versione per i float float somma(float e,float f) { return(e+f); } /////////////////////////////////////////////////////////////////////////// // Il main... /////////////////////////////////////////////////////////////////////////// int main(void) { int mioint1 = 15; // Variabile di tipo int int mioint2 = 50; // Variabile di tipo int long miolong1 = 150000; // variabile di tipo long long miolong2 = 1666000; // variabile di tipo long float miofloat1 = 3.02; // Variabile di tipo float float miofloat2 = 32.24; // Variabile di tipo float // Ora sommiamo coppie di variabili di 3 tipi diversi usando sempre somma() cout << mioint1 << " + " << mioint2 << " = "; cout << somma(mioint1,mioint2) << "\n"; cout << miolong1 << " + " << miolong2 << " = "; cout << somma(miolong1,miolong2) << "\n"; cout << miofloat1 << " + " << miofloat2 << " = "; cout << somma(miofloat1,miofloat2) << "\n"; return 0; // main() restituisce 0 } /* L'overloading permette di accedere ad un unsieme di metodi simili (almeno * a livello logico) usando lo stesso nome. * Naturalmente un'altra comodita' del polimorfismo e' quella di aggiungere * dei parametri opzionali ad una funzione, ad esempio si puo' fare in * modo che un metodo "mettiorario" possa accettare l'ora sia come 3 interi, * ore,minuti,secondi, che come stringa di testo "HH:MM:SS", che come un * singolo intero che rappresenti il numero di secondi passati dalle 00:00, * e opzionalmente si possa immettere un testo. I casi possibili saranno: * * mettiorario(16,28,5); * mettiorario("16:28:05"); * mettiorario(58805); * mettiorario(16,28,5, "oggi sono contento"); * mettiorario("16:20:05", "oggi sono contento"); * mettiorario(58805, "oggi sono contento"); * * Come si vede, 6 funzioni tutte con lo stesso nome. La sua documentazione * sarebbe qualcosa di simile: * * ------------------------------------------------------------------------- * mettiorario(ora, messaggio opzionale) * * ora = uno di questi 3 formati: * * int,int,int ; ore, minuti, secondi * "HH:MM:SS" ; stringa * long ; n. secondi dall'inizio del giorno. * ------------------------------------------------------------------------- * * Il tutto e' molto semplice. Immaginatevi a dover documentare cio' con * 6 funzioni di nome diverso a seconda dei parametri da passare! */