Funzioni e costanti

Abbiamo già visto che nell'ambito delle funzioni la parola chiave const può essere utilizzata all'interno dei parametri per far sì che gli argomenti passati siano costanti.

Una funzione però oltre a dei dati in ingresso, come sappiamo ha anche dei dati in uscita.
E se volessimo che questi dati fossero costanti?

Vediamo prima di tutto perché mai dovremmo:

il nostro programma di esempio è formato da una struttura Utente, che è composta da due membri, età e altezza;

abbiamo poi una funzione che accetta in ingresso un'età ed un'altezza, e restituisce in uscita una variabile di tipo Utente;

all'interno della funzione main() richiamiamo la funzione inserendo la nostra età e la nostra altezza, e la funzione si occupa di creare una variabile di tipo Utente contenente l'età e l'altezza da noi inserite, e restituisce questa variabile;

infine assegniamo il contenuto della variabile restituita dalla funzione all'interno di una variabile (io l'ho chiamata "pietro") di tipo Utente creata da noi;

questo è del tutto legale dal momento che sia la variabile restituita dalla funzione che la variabile creata da noi sono di tipo Utente;

a questo punto possiamo utilizzare la nostra variabile per visualizzare l'età e l'altezza inseriti tramite la funzione;
struct Utente {
int età;
float altezza;
};

Utente creaUtente(int an, float alt) // !!! restituisce una variabile di tipo Utente
{
Utente unUtente; //crea una variabile di tipo Utente

unUtente.altezza = alt; //salva l'altezza inserita
unUtente.età = an; //salva l'età inserita

return unUtente; // !!! restituisce una variabile di tipo Utente
}

int main()
{
Utente pietro; //crea una variabile di tipo utente

pietro = creaUtente(24, 180); //la funzione restituisce una variabile di tipo utente

cout << pietro.età; //tramite la nostra variabile visualizziamo l'età

return 0;
}
Come possiamo vedere la funzione creaUtente() restituisce una variabile di tipo Utente, mentre all'interno della funzione main() richiamiamo la funzione creaUtente() che restituisce la variabile appena creata, e noi copiamo il suo contenuto all'interno della nostra variabile, nel mio caso la variabile pietro.

Cosa succede se, nel punto in cui richiamiamo la funzione, facciamo una cosa del genere?
creaUtente(24, 180).età = 12;
Sostituite alla funzione la variabile sostituita e tutto sarà più chiaro.
Infatti la riga di codice precedente è equivalente a:

unUtente.età = 12; //la variabile unUtente è quella restituita dalla funzione creaUtente()

In altre parole la funzione stessa può essere utilizzata per modificare la variabile restituita. Naturalmente in questo caso non succede niente, ma si possono presentare dei casi in cui la modifica della variabile (o oggetto) restituita non dev'essere consentita.
Ad esempio quando la variabile restituita è un puntatore ad un oggetto esterno alla funzione, e modificando il puntatore durante una chiamata a funzione modifichiamo anche l'oggetto originale puntato da esso.

Per ovviare a questo è possibile dichiarare const il tipo restituito:
const Utente creaUtente(int an, float alt) // !!! restituisce una variabile costante
{
Utente unUtente; //crea una variabile di tipo Utente

unUtente.altezza = alt; //salva l'altezza inserita
unUtente.età = an; //salva l'età inserita

return unUtente; // !!! ora unUtente è costante e non può essere modificato dall'esterno
}
In questo modo l'istruzione seguente non è più permessa:

creaUtente(24, 180).altezza = 178;

Bisogna inoltre ricordarsi di aggiungere la parola const anche al prototipo della funzione:

const Utente creaUtente(int, float);

Nessun commento:

Posta un commento