Perché c'è bisogno di parametri di riferimento in C ++?

5

Abbiamo imparato a conoscere i parametri di riferimento nella mia classe Introduzione alla programmazione. Capisco perfettamente che i parametri di riferimento ti danno accesso al luogo in cui un argomento è tenuto in memoria, mentre i parametri di valore creano copie degli argomenti.

Perché dovrei desiderare che la mia funzione abbia accesso alla posizione della memoria dell'argomento anziché al suo valore?

    
posta moonman239 08.03.2016 - 20:22
fonte

3 risposte

13

Ci sono alcuni motivi per cui potrebbe essere utile.

Tipi non copiabili

Non tutto può essere passato per valore! std::unique_ptr , ad esempio, può essere spostato, non copiato, perché non ha senso copiare qualcosa che ha proprietà uniche su una risorsa. Il suo costruttore di copie è stato "cancellato", il che significa che passarlo per valore in una funzione semplicemente fallirà.

Tipi di grandi dimensioni

Forse la tua funzione ha solo bisogno di ispezionare il valore corrente dell'oggetto, senza effettivamente cambiarlo. Se l'oggetto è grande, la copia è inutile e inutile. Non solo stai prendendo più cicli di memoria e CPU di quelli di cui hai bisogno, ma se hai una ricorsione profonda, sì puoi davvero contribuire alla probabilità di un sovraccarico di stack perché i tuoi stack frame sono molto più grandi di quanto dovrebbero essere. p>

In genere, in questi scenari, passeremo da const di riferimento per evitare le mutazioni accidentali.

Mutation

Forse l'oggetto viene passato come parametro "out", in modo che le modifiche apportate all'interno della funzione siano visibili nel sito di chiamata. Ecco un esempio:

bool foo(std::string& a)
{
    const char* result = someSysCall("...");
    if (result) {
       a = result;
       return true;
    }
    else {
       return false;
    }
}

int main()
{
    std::string str;
    if (foo(str)) {
       // do things with str
    }
    else {
       // show an error?
    }
}

Mentre spesso usiamo le eccezioni invece di questo schema, i parametri out sono ancora diffusi in molte librerie (in particolare l'API di Windows). Spesso vengono implementati utilizzando puntatori, ma il principio è esattamente lo stesso.

    
risposta data 10.03.2016 - 23:31
fonte
3

C passa con avere valori e puntatori. C ++ aggiunge riferimenti.

Molto di questo è per supportare il sovraccarico dell'operatore. Ad esempio, supponiamo di voler sovraccaricare operator -- o operator = per un determinato tipo. Entrambi questi (e molti altri ancora) devono modificare l'oggetto che ricevono come parametro.

Ora, in C, quando è necessario che una funzione modifichi qualcosa, si passa un puntatore a quel qualcosa. Tuttavia, quando hai a che fare con un operatore sovraccarico, non hai questa opzione. Se hai codice come ++foo; o foo -= bar; , non hai alcun modo reale per specificare che per questo caso, voglio passare l'indirizzo di foo invece del suo valore. Per passare l'indirizzo, devi prendere l'indirizzo nel sito di chiamata, così ti ritroverai con cose come

scanf("%d", &destination);

I riferimenti consentono di ottenere più o meno lo stesso risultato, ma la sintassi per farlo è interamente nella funzione chiamata piuttosto che nel sito di chiamata, quindi un'espressione normale con sintassi normale può ancora passare riferimento in modo che la funzione chiamata possa modificare il suo parametro.

Sebbene ci siano sicuramente altri usi perfettamente validi per i riferimenti in C ++, e il loro utilizzo può essere (spesso è) più pulito e sicuro rispetto all'uso di un puntatore, la maggior parte degli altri casi potrebbe essere fatto usando un puntatore se i riferimenti non erano disponibili. Questo caso richiede praticamente un riferimento: semplicemente non funzionerà con un puntatore.

    
risposta data 17.03.2016 - 16:59
fonte
-5

Ah! Qualcosa mi è venuto in mente: la ricorsione. Se una funzione ricorsiva necessita di accedere a una variabile e si desidera che la funzione trasmetta tale variabile a se stessa, allora si desidera, e potrebbe essere necessario, un parametro di riferimento. Altrimenti, stai solo assegnando memoria non necessaria e, di fatto, potresti causare uno "stack overflow".

Modifica: alcune persone hanno notato che esistono dei puntatori. In ogni caso, le variabili di riferimento sono talvolta preferibili semplicemente perché rendono inutili referenziamento e dereferenziazione.

    
risposta data 08.03.2016 - 20:30
fonte

Leggi altre domande sui tag