2014-11-27 17 views
7

Da quello che so, i riferimenti sono solo un altro nome per una variabile mentre i puntatori sono la loro variabile. I puntatori occupano spazio. Le persone spesso dicono "usa un riferimento o un puntatore" ma non dicono che è meglio. Se i riferimenti non hanno memoria propria, allora i riferimenti vincono in quel dipartimento. Quello che non so è se il compilatore fa una distinzione tra riferimenti e variabili normali. Se si eseguono operazioni su un riferimento, esso viene compilato con lo stesso codice della variabile normale?I riferimenti o i puntatori sono più veloci?

+1

W.r.t. prestazioni, probabilmente non molto (esegui alcune misurazioni per verificare sulla tua piattaforma). Penso che sia più importante chiarire la semantica che vuoi - tenere a mente, i puntatori possono essere NULL, quindi si può sostenere che siano opzionali. – Niall

+3

I riferimenti sono puntatori mascherati, l'unico vantaggio in termini di prestazioni può derivare da alcune supposizioni aggiuntive che il compilatore può fare su di loro (non possono essere legalmente ripristinati, né possono essere NULL). –

+0

Al contrario, un utente potrebbe avere troppa paura di passare il puntatore NULL anche se il parametro puntatore è progettato per essere facoltativo. –

risposta

3

Anche i riferimenti interni sono implementati in termini di puntatori. Quindi, è difficile dire quale sia il puntatore/riferimento più veloce.

È un utilizzo di questi due che fa la differenza.

Ad esempio, si desidera passare un riferimento a un parametro alla funzione.

void func(int& a) case_1 
{ 
    //No need to check for NULL reference... 
} 
void func(int* a) case_2 
{ 
    //Need o check if pointer is not NULL 
} 

In case_2 Devi controllare in modo esplicito se il puntatore non è NULL prima dereferncing è che tale non è il caso con i riferimenti perché i riferimenti vengono inizializzati a qualcosa.

ipotesi è che si sta giocando gioco in modo civile cioè

non si sta facendo qualcosa di simile a: -

int*p = NULL; 
int &a = *p; 
+0

La prima parte ha assolutamente ragione. Tuttavia, in pratica, molti controlli NULL non sono richiesti. Basta documentare nel commento della funzione che si prevede un puntatore non NULL e lasciare che la pagina null blocchi il programma se tale precondizione non viene soddisfatta. – cmaster

+0

In pratica si verificano molti errori di segmentazione a causa del cattivo accesso puntatore. – ravi

+1

In pratica puoi ottenere tanti segoults a causa di un cattivo accesso di riferimento ... – cmaster

1

Sono gli stessi, i riferimenti sono solo un meccanico lingua che è un puntatore che non può essere nullo La differenza rimane solo nella fase di compilazione, dove riceverai un reclamo se provassi a fare qualcosa di illegale.

+0

Possono essere in pratica NULL, anche se lo standard di linguaggio chiama il comportamento non definito alla creazione di un riferimento NULL. L'effetto è lo stesso di un puntatore NULL. Solo più difficile eseguire il debug, dal momento che molte persone si affaticheranno con l'illusione che i riferimenti non possono essere NULL, e di conseguenza non capiscono cosa sta succedendo nel loro codice. – cmaster

+0

Possono essere, ma il codice può sempre presumere che non lo siano. – mukunda

+0

È possibile utilizzare la stessa ipotesi su un puntatore, con le stesse conseguenze. – cmaster

1

Qui sono i miei due programmi di test:

Riferimento:

int i = 0; 
int& r = i; 
++r; 
int j = 0; 
++j; 

Pointer:

int i = 0; 
int* r = &i; 
++(*r); 
int j = 0; 
++j; 

mio compilatore ha scritto lo stesso codice assembly esatta per entrambi.

movl $0, -16(%rbp) #, i 
leaq -16(%rbp), %rax #, tmp87 
movq %rax, -8(%rbp) # tmp87, r 
movq -8(%rbp), %rax # r, tmp88 
movl (%rax), %eax # *r_1, D.31036 
leal 1(%rax), %edx #, D.31036 
movq -8(%rbp), %rax # r, tmp89 
movl %edx, (%rax) # D.31036, *r_1 
movl $0, -12(%rbp) #, j 
addl $1, -12(%rbp) #, j 
movl $0, %eax #, D.31036 
+0

Puoi eseguire il dump dell'assembly con flag di ottimizzazione come '-O3' o' -O2' e confrontare di nuovo. –

+0

Dump migliore con '-Os', produce il codice assembler più leggibile. – cmaster

+0

Non voglio farlo perché ottimizzerà l'intero codice, cosa non utile. – user4298783

Problemi correlati