Il dereferenziamento di un puntatore e il passaggio a una funzione che prende il suo argomento per riferimento crea una copia dell'oggetto?Il dereferenziamento di un puntatore ne fa una copia?
risposta
In questo caso il valore sul puntatore viene copiato (sebbene ciò non sia necessariamente il caso in cui l'ottimizzatore può ottimizzarlo).
int val = *pPtr;
In questo caso però non copia si svolgerà:
int& rVal = *pPtr;
La ragione nessuna copia avviene perché un riferimento non è un costrutto livello codice macchina. È un costrutto di livello superiore e quindi è qualcosa che il compilatore usa internamente piuttosto che generare un codice specifico per esso.
Lo stesso, ovviamente, va per i parametri di funzione.
Non è il puntatore che viene copiato nel primo caso. È il valore a cui punta che viene copiato. Nel secondo caso, il puntatore viene copiato (logicamente) e il valore non lo è. –
@Sergey: buoni punti che sono stati formulati molto male :) – Goz
Ho scritto un semplice programma di test per verificare le risposte da solo, si spera che questo aiuti alcuni http://codepad.org/XDqahndf – RishiD
Speriamo che non lo sia: sarebbe se la funzione chiamata prendesse il suo argomento in base al valore.
Inoltre, questo è il comportamento previsto di un riferimento:
void inc(int &i) { ++i; }
int main()
{
int i = 0;
int *j = &i;
inc(*j);
std::cout << i << std::endl;
}
Questo codice si prevede di stampare 1
perchéinc
prende il suo argomento per riferimento. Se una copia fosse stata effettuata sulla chiamata inc
, il codice avrebbe stampato 0
.
No. Un riferimento è più o meno proprio come un puntatore con notazione diversa e la restrizione che non vi è alcun riferimento nullo. Ma come un puntatore contiene solo l'indirizzo di un oggetto.
"Ma come un puntatore contiene solo l'indirizzo di un oggetto." Il riferimento non ha un'esistenza propria. È solo un alias dell'oggetto a cui è stato inizializzato. Quindi dire "contiene" l'indirizzo sarà sbagliato. Il riferimento punta solo allo stesso indirizzo dell'oggetto originale, non contiene quell'indirizzo. –
Perché no? Come può indicare da qualche parte e non contenere l'indirizzo? Lo contiene, solo tu non puoi accedere all'indirizzo che contiene perché viene automaticamente cancellato ogni volta che lo accedi. –
@Sergey Tachenov: Il compilatore deve creare la finzione che si tratta di un alias e può assumerlo. Ciò significa che, a seconda dell'uso, il compilatore può creare un puntatore * interno * e automaticamente dereferenziare l'uso, o in alcuni casi può semplicemente riferirsi completamente all'oggetto originale. Nella maggior parte dei casi deve ricorrere ai puntatori, ma alla fine della giornata, è meglio pensare in termini astratti: i riferimenti sono * alias * indipendentemente da come sono implementati. –
Nel caso semplice, n. Ci sono casi più complicati, però:
void foo(float const& arg);
int * p = new int(7);
foo(*p);
Qui, si crea un oggetto temporaneo, perché il tipo di puntatore Dereferenced (int
) non corrisponde al tipo di base del parametro di funzione (float
). Esiste una sequenza di conversione e il temporaneo convertito può essere associato a arg
poiché si tratta di un riferimento const.
Re: il titolo. Se il dereferenziamento di un puntatore crea una copia dell'oggetto, non sarebbe impossibile usare mai l'oggetto ?! – visitor