2014-08-29 19 views
6

mi è stato dato un codice (C++), dove sono passati gli array usandoPerché passare array come "int * & name"?

void fun(int *& name){...} 

ma qual è l'idea alla base di questo? Immagino che significhi "una serie di riferimenti" ma quando si passa un puntatore al primo elemento sarebbe bello, no? Quindi qual è la motivazione per farlo in questo modo?

+3

Significa riferimento a una variabile di puntatore. Lo scopo è quello di cambiare la variabile puntatore passata ad esso. –

+3

matrici? Non è possibile passare oggetti array reali attraverso tale parametro. Quello che puoi passare è un * puntatore * che punta a qualche elemento dell'array, ma non all'array stesso. Ad esempio, non sarà possibile passare direttamente una matrice 'int a [10]' a questa funzione. – AnT

+0

È importante sapere che ** gli array non sono puntatori e che i puntatori non sono matrici **. Vedi [** questo post **] (http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c) per ulteriori informazioni. – juanchopanza

risposta

5

La funzione riceve un riferimento a un puntatore. Ciò significa che la funzione non può solo modificare lo puntato da name, ma anche che le modifiche al puntatore stesso effettuate all'interno della chiamata di funzione saranno visibili anche all'esterno.

Esempio:

#include <iostream> 

int* allocate() 
{ 
    return new int(); 
} 

void destroy(int*& ptr) 
{ 
    delete ptr; 
    ptr = NULL; 
} 

int 
main(int argc, char *argv[]) 
{ 
    int* foo = allocate(); 

    std::cout << foo << std::endl; 

    destroy(foo); 

    std::cout << foo << std::endl; 

    return 0; 
} 

uscita è:

0x82dc008 
0 
1

Ciò significa che la funzione può modificare il valore del puntatore con il chiamante.

cioè

myName* foo; /* ToDo - initialise foo in some way*/ 
fun(foo); 
/* foo might now point to something else*/ 

mi considerano questo come un anti-modello. La ragione per cui le persone che leggono il tuo codice non sono foo da modificare in modo tale che la sintassi di chiamata non sia distinguibile dalla più normale funzione void anotherFun(int * name){...}.

La stabilità di tale codice può risentirne. Pertanto, ti consigliamo di utilizzare void fun(int ** name){...}. La sintassi di chiamata diventa quindi fun(&foo) che indica all'utente della funzione che è possibile modificare foo.

+1

Direi che è un anti-pattern per usare un puntatore quando puoi usare un riferimento. Ma farei anche qualcosa di diverso: 'int * fun (int * name);', e restituisco il nuovo valore. – juanchopanza

+0

Beh, personalmente non mi piace il puntatore alla sintassi del puntatore dove non è realmente necessario. Quindi dipende dalle preferenze personali. Tuttavia, sono d'accordo sul fatto che in generale potrebbe risultare inaspettato per il chiamante che il puntatore può essere modificato. Un'alternativa all'utilizzo di 'int **' come si propone è di avere un'API chiara e ben documentata con nomi ben scelti per le funzioni, ad es. 'deleteAndSetNull (int * & ptr)' per una funzione che cancella un puntatore e lo imposta su NULL. – oxygene

+0

È divertente come questo diventi: ovviamente rispetto la tua opinione e come la proposta di usare 'int * fun (int * name)'. Non mi piacciono i riferimenti usati nel modo in cui l'OP ha perché rendono il codice difficile da leggere e i bug possono essere introdotti da junior che lavorano su progetti collaborativi. Almeno usa un 'const &' se possibile. – Bathsheba