User Tools

Site Tools


appunti3s:cenni_ai_references
no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


appunti3s:cenni_ai_references [2020/06/08 22:19] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== Premessa ======
 +Sia nel linguaggio C che in C++ si può effettuare il passaggio di parametri esclusivamente //per valore//, cioè copiando il contenuto delle variabili indicate tra parentesi.
 +Vedere esempio [[appunti3s:programmi_procedurali#passaggio_per_valore]].
 +Questo impedisce di effettuare delle modifiche sui //parametri effettivi// della funzione.
 +<code>int triplicare(int x)
 +{
 + x=x*3; // modifica solo la var. locale x
 + return x;
 +}
 +</code>
 +
 +Tuttavia, se al posto dei tradizionali tipi di dato (come //int//) si usano i puntatori (come //int*//), la funzione riesce ad accedere e a modificare anche i //parametro effettivi//
 +<code>int triplicare(int* p)
 +{
 + *p=*p*3;  // modifica anche la variabile puntata da p
 + return *p;
 +}
 +</code>
 +Come si può notare dal secondo esempio, questo appesantisce il codice costringendo ad aggiungere l'operatore di deferimento //*// (l'asterisco) davanti al puntatore //p//.
 +
 +I //references//, invece, hanno la stessa "forza" dei puntatori, ma una sintassi molto semplice.
 +
 +====== References ======
 +
 +Quando una funzione ha come //parametro formale// un reference, al suo interno NON viene crea una nuova variabile locale, ma si lavora proprio sul //parametro effettivo// usando il parametro formale come il suo soprannome temporaneo.
 +<code>void triplicare(int& x); </code>
 +La dichiarazione si legge in questo modo:
 +la funzione accetta come argomento un //reference a...// intero.
 +
 +Purtroppo il simbolo //&//, usato in un altro luogo, possiede anche altri significati, completamente diversi. Dentro un'espressione logica può significare operatore //AND binario//, oppure scirtto davanti al nome di una variabile, operatore //indirizzo di//. 
 +Il reference al momento della sua dichiarazione __deve__ essere sempre inizializzato, infatti non si può usare un soprannome senza dire a chi corrisponde quell'alias... Al contrario dei puntatori, i reference, una volta inizializzati come alias ad un oggetto, non possono diventare l'alias di niente altro.
 +
 +<file cpp 20.cpp>
 +// Questo programma è stato scritto da Fabio.
 +// Serve a calcolare il triplo di un numero.
 +
 +#include <iostream>
 +
 +// questo modo di passare il parametro 
 +// non crea una copia locale
 +// questa funzione e' di tipo void, cioe' non restituisce nulla (manca return)
 +
 +void triplicare(int& x) 
 +{
 +  x = 3*x;
 +}
 +
 +int main ()
 +{
 +  int mioNumero,mioTriplo;
 +
 +  std::cout << "Per favore scrivi un numero intero: ";
 +  std::cin >> mioNumero;
 +  
 +  triplicare(mioNumero); // chiamata della funzione che modifica il mioNumero
 +  
 +  std::cout << "il triplo vale " << mioNumero << ".\n";
 +  return 0;
 +}
 +</file>
 +
 +====== references costanti ======
 +
 +Premettendo //const// davanti ad un reference si __impedisce__ di modificare il //parametro effettivo//. L'effetto è simile al classico passaggio per valore, ma con la differenza che invece di creare una copia del parametro effettivo, in pratica si copia solo il suo indirizzo.
 +
 +Questo è utilizzato soprattutto quando il parametro effettivo è un "oggetto" (difficile da copiare o di notevoli dimensioni). 
 +
 +<file cpp 21.cpp>
 +// Questo programma è stato scritto da Fabio.
 +
 +#include <iostream>
 +
 +// questo modo di passare il parametro 
 +// passa l'indirizzo di memoria di questo parametro
 +// il termine const evita modifiche indesiderate al parametro.
 +
 +// NON creando una nuova variabile x, risparmio memoria!
 +// x è solo il soprannome temporaneo che viene dato a mioNumero
 +
 +int triplicare(const int& x)  
 +{
 + return 3*x;
 +}
 +
 +int main ()
 +{
 +  int mioNumero;
 +
 +  std::cout << "Per favore scrivi un numero intero: ";
 +  std::cin >> mioNumero;
 +  
 +  std::cout << "il triplo di " << mioNumero
 +            << " vale " << triplicare(mioNumero) ".\n";
 +  return 0;
 +}
 +</file>
 +
 +<file cpp 22.cpp>
 +// Questo programma è stato scritto da Fabio.
 +
 +// Serve a calcolare il triplo di un numero.
 +// I reference sono utili per risparmiare memoria
 +// anche sul tipo restituito dalla funzione
 +// basta aggiungere UN SECONDO reference (sempre preceduto da un const)
 +
 +#include <iostream>
 +
 +const int& triplicare(const int& x)  
 +{
 + return 3*x;
 +}
 +
 +int main ()
 +{
 +  int mioNumero;
 +
 +  std::cout << "Per favore scrivi un numero intero: ";
 +  std::cin >> mioNumero;
 +  
 +  std::cout << "il triplo di " << mioNumero
 +            << " vale " << triplicare(mioNumero) ".\n";
 +  return 0;
 +}
 +</file>
 +
 +Il nuovo alias davanti alla funzione evita di creare una nuova variabile temporanea che sarebbe necessaria anche per restituire il valore con //return//
 +Il nuovo //const// davanti alla funzione impedisce modifiche indesiderate a tale oggetto locale.
 +
 +I const reference sono anche l'unico modo con cui si possono utilizzare gli oggetti temporanei inaccessibili (come le espressioni costanti o gli oggetti temporanei restituiti da una funzione)
 +
 +vedere //Thinking in C++, capitolo 11: References & the Copy-Constructor pag.477//
 +
 +====== Funzioni costanti ======
 +
 +Le funzioni costanti sono importanti perché sono un buono strumento di correzione degli errori.
 +Basta aggiungere un modificatore //const// in fondo (alla fine) della firma della funzione.
 +Questo evita modifiche accidentali ai dati degli oggetti
 +
 +Basta scrivere //const// __in fondo__ al nome della funzione per costringere il compilatore a fare un controllo che quella funzione non esegua alcuna istruzione di modifica su TUTTI i membri dato di quell'oggetto. Per questo motivo dovrebbe essere usato su tutte le funzioni di tipo ispettore (vedi [[appunti3s:programmi_procedurali#classificazione|classificazione delle funzioni]])
 +
 +Le funzioni di questo tipo sono anche le uniche che possono avere come argomenti interi oggetti costanti come:
 +  * const Classe unOggetto
 +  * const& Classe unOggetto
 +  * const Classe* unOggetto
  
appunti3s/cenni_ai_references.txt · Last modified: 2020/06/08 22:19 by 127.0.0.1