2010-11-06 2 views
9

Possibili duplicati:
How to pass objects to functions in C++?
is there any specific case where pass-by-value is preferred over pass-by-const-reference in C++?È meglio passare per valore o per riferimento per i tipi di dati di base?

Ho membri di una classe implementata in questo modo:

void aaa(int a, float b, short c) 
{ 
    bbb(a, b); 
} 

void bbb(int a, float b) 
{} 

Se i valori di A, B e C sono stati memorizzato nella mia classe come costanti, quindi sarebbe stato meglio/ragionevole da usare le mie funzioni come mostrato di seguito o come mostrato sopra?

void aaa(int& a, float& b, short& c) 
void bbb(int& a, float& b) 

costa usare i riferimenti danno alcun beneficio di velocità o vantaggi in questo caso? Eventuali svantaggi/spese generali di riferimento qui?

+1

Ok, che sono tutti quelli '' * su ?! –

+0

Suppongo che sia necessario modificare il formato int ** e ** non ha senso :-) –

+0

Gli asterix sono stati aggiunti da StackOverflow. Il sito doveva collegare le lettere tra asterischi a grassetto. Lo rimuoverò perché non si sta convertendo. – Nav

risposta

4

standard non ha vincoli circa l'attuazione di riferimenti, però di solito stanno implementati come puntatori autodereferenced (in realtà con alcune eccezioni). Come probabilmente sapete, il 32 bit dimensioni puntatore di sistema è di 4 byte, il che significa che il passaggio chars, shorts (tipi con sizeof() meno di 4 byte) con riferimento forse considerato come un po 'overkilling - utilizzando 4 byte invece di 1 (char) o 2 (breve). In generale dipende se i rigisters o stack viene utilizzato per passare parametri: è possibile salvare un po 'di stack quando passa tipi fondamentali per valore, tranne nel caso di registri anche per caratteri, saranno utilizzati 4 byte, quindi è inutile nel tentativo di ottimizzare qualcosa con ptrs/refs.

+0

Si noti che c'è un'altra differenza nelle prestazioni: quando si utilizza un int direttamente, il valore è presente nel registro o nello stack, mentre quando si passa il riferimento (assumendo un puntatore auto-dereferenziato) il valore attuale deve essere recuperato con un extra indiretta, che non sarebbe necessaria se passasse per valore. –

+0

-1 Per propagare idee errate sull'utilizzo dello stack. Passare un 'char', ad esempio, nello stack, in genere utilizza 4 byte di spazio di stack su un sistema a 32 bit. In C e C++ la stessa ragione di fondo si riflette nella promozione automatica su 'int'. In breve, l'uso dello spazio nello stack non ha nulla a che fare con esso per i piccoli tipi. Invece ha a che fare con il tempo del programmatore, quanto hai bisogno di scrivere e quanto hai bisogno di leggere, cioè l'efficienza del programmatore, e ha a che fare con una possibile ulteriore indiretta, cioè l'efficienza del programma. –

+0

Uh, chi ha votato di nuovo questa risposta errata? –

3

Se si utilizzano i riferimenti, renderli const:

void bbb(const int & a, const float & b); 

In caso contrario, la semantica saranno diversi da passaggio per valore, in quanto la funzione potrebbe cambiare il valore delle variabili passate ai parametri. Ciò implicherebbe che non è possibile utilizzare letterali per gli argomenti.

1

non vedo il motivo per cui sarebbe più veloce. È necessario inviare il parametro alla funzione in entrambi i casi. Se la funzione ottiene il puntatore invece del valore, allora il puntatore necessita di un dereferenziamento che potrebbe essere più lento dell'invio di un valore normale.

+0

In caso di un puntatore '' *, ci sarà dereferenziazione, in caso di riferimento * * '&', non ci sarà "sovraccarico" coinvolti. Per i tipi più grandi di registro nativo utilizzato per argomenti della funzione (normalmente la dimensione di un indirizzo di memoria), è in teoria meglio passare riferimenti anziché oggetti interi per valore. – rubenvb

+0

@rubenvb: Il fatto che non è necessario in modo esplicito dereference non significa che non v'è alcun dereference implicita. In molti (tutti?) Compilatori, i riferimenti sono implementati come puntatori automaticamente dereferenziati. L'utilizzo di un riferimento implica un'indirizzamento implicito nell'assemblatore generato (a meno che la funzione non sia in linea - dove il compilatore può utilizzare le variabili effettive) –

+0

Penso che stiamo parlando di qualcosa come 'int' o' float'. Tuttavia, * e & è praticamente solo una sintassi diversa per il parametro pointer-type, quindi immagino che David sia proprio qui. – tia

4

Nel caso di tipi ordinali - cioè int, float, bool, ecc. - non è possibile risparmiare utilizzando un riferimento invece di utilizzare semplicemente il passaggio per valore. SourceSource2