Overloading delle funzioni, argomenti di default e argomenti const

Ormai sappiamo bene come scrivere una funzione.
Ma cosa succede se una funzione richiede il passaggio di tot argomanti, ma non sempre sappiamo in anticipo quali argomenti passare ad una funzione?

Una soluzione al problema è data dagli argomenti di default.
Vediamo subito un esempio:

int calcolaPotenza(int base, int esponente)
{

La nostra funzione richiede in ingresso il passaggio di una base e di un esponente e restituisce in uscita il risultato della potenza.
Se volessimo far sì che, se l'utente passa solo la base, la funzione calcoli implicitamente il quadrato (e cioé utilizza l'esponente 2), possiamo utilizzare gli argomenti di default:

int calcolaPotenza(int base, int esponente = 2)
{

In questo modo, se l'utente specifica l'esponente viene calcolata la potenza in base ad esso, altrimenti viene utilizzato un esponente uguale a 2:

calcolaPotenza(3, 4); //esegue 3^4
calcolaPotenza(3); //esegue 3^2

Nel secondo caso l'utente non passa l'esponente, perciò la funzione utilizza l'argomento di default esponente = 2.

L'overloading delle funzioni permette invece di richiamare una funzione diversa in base al numero o al tipo di parametri passati.
Le funzioni devono avere lo stesso nome ma, perché il compilatore riesca a distinguerle, devono differire nel tipo o nel numero dei parametri passati:

int somma(int, int);

int somma(int, int, int);

Entrambe le funzioni hanno lo stesso nome, ma la prima somma due numeri, mentre la seconda ne somma tre.
Quando, all'interno del nostro programma, andiamo a chiamare la funzione somma, il compilatore riesce a capire quale funzione utilizzare delle due, in base al numero di parametri che le passiamo:

somma(2, 3); //chiama la prima funzione

somma(3, 4, 2); //chiama la seconda funzione

Lo stesso succede con i tipi dei parametri:

float somma(float, float);

int somma(int, int);

somma(1.3, 8,22); //chiama la prima funzione

Abbiamo due funzioni con lo stesso numero di parametri, ma la prima accetta due float, mentre la seconda accetta due int.

Quando poi andiamo a chiamarare la funzione, il compilatore capisce che si tratta della prima perché gli argomenti passati sono due numeri decimali (float).

E' importante sapere che il tipo di ritorno non può essere utilizzato come discriminante tra due funzioni per l'overloading:

float random();

int random();

random(); //ERRATO! il compilatore non sa quale delle due funzioni richiamare

Le due funzioni si differenziano solo per il tipo restituito, ed è chiaro che il compilatore non può capire quale delle due funzioni chiamare.

Cosa succede invece se vogliamo passare ad una funzione il riferimento ad un argomento che non vogliamo sia modificato? Semplice, dichiariamo il rispettivo parametro come const:

void funzione(const int &param1);

In questo modo accederemo alla variabile in sola lettura. Potremo cioè leggerne il contenuto ma non modificarla.

Lo stesso discorso ovviamente vale per i parametri puntatore:

void funzione(const int* param1);

L'area di memoria puntata da param1 potrà essere letta ma non modificata.

Nessun commento:

Posta un commento