2010-12-14 6 views

Antwort

22

In diesem Fall wird der Wert am Zeiger kopiert (obwohl dies nicht unbedingt der Fall ist, da der Optimierer dies optimieren kann).

int val = *pPtr; 

In diesem Fall wird jedoch keine Kopie statt:

int& rVal = *pPtr; 

Der Grund keine Kopie stattfindet, weil ein Verweis kein Maschinencode-Ebene Konstrukt ist. Es ist ein Konstrukt auf höherer Ebene und wird daher vom Compiler intern verwendet, anstatt dafür spezifischen Code zu generieren.

Das gleiche gilt natürlich für Funktionsparameter.

+4

Es ist nicht der Zeiger, der im ersten Fall kopiert wird. Es ist der Wert, auf den es zeigt, der kopiert wird. Im zweiten Fall wird der Zeiger (logisch) kopiert und der Wert nicht. –

+0

@Sergey: Gute Punkte, die sehr schlecht formuliert wurde :) – Goz

+2

Ich schrieb ein einfaches Testprogramm, um die Antworten für mich selbst zu überprüfen, hoffentlich hilft das einige http://codepad.org/XDqahndf – RishiD

3

Hoffentlich tut es nicht: es wäre, wenn die aufgerufene Funktion ihr Argument nach Wert nimmt.

Außerdem, das ist das erwartete Verhalten einer Referenz:

void inc(int &i) { ++i; } 

int main() 
{ 
    int i = 0; 
    int *j = &i; 
    inc(*j); 
    std::cout << i << std::endl; 
} 

Dieser Code wird erwartet 1weilinc nimmt ihr Argument durch Bezugnahme zu drucken. Wäre eine Kopie unter inc Aufruf erstellt worden, würde der Code 0 drucken.

3

Nein. Eine Referenz ist mehr oder weniger genau wie ein Zeiger mit unterschiedlicher Schreibweise und der Einschränkung, dass es keine Nullreferenz gibt. Aber wie ein Zeiger enthält es nur die Adresse eines Objekts.

+2

"Aber wie ein Zeiger enthält es nur die Adresse eines Objekts." Die Referenz hat keine eigene Existenz. Sie ist nur ein Alias ​​für das Objekt, für das sie initialisiert wurde. Also sagt "es enthält" -Adresse falsch. Die Referenz verweist nur auf die gleiche Adresse wie das ursprüngliche Objekt, sie enthält diese Adresse jedoch nicht. –

+0

Warum nicht? Wie kann es irgendwo zeigen und die Adresse nicht enthalten? Es enthält es, nur Sie können nicht auf die Adresse zugreifen, die es enthält, da es bei jedem Zugriff automatisch dereferenziert wird. –

+0

@Sergey Tachenov: Der Compiler muss die Fiktion erstellen, dass es ein Alias ​​ist, und kann es übernehmen. Dies bedeutet, dass der Compiler abhängig von der Verwendung einen * internen * Zeiger erstellen und ihn bei der Verwendung automatisch dereferenzieren kann, oder in einigen Fällen kann er nur auf das ursprüngliche Objekt verweisen. In den meisten Fällen muss man auf Zeiger zurückgreifen, aber am Ende des Tages denkt man besser abstrakt: Referenzen sind * Aliase *, unabhängig davon, wie sie implementiert sind. –

6

Im einfachen Fall, nein. Es gibt kompliziertere Fälle, aber:

void foo(float const& arg); 
int * p = new int(7); 
foo(*p); 

Hier wird ein temporäres Objekt erstellt wird, weil der Typ des dereferenzierten Zeigers (int) Art des Funktionsparameters der Basis stimmt nicht überein (float). Es existiert eine Konvertierungssequenz, und das konvertierte temporäre Objekt kann an arg gebunden werden, da dies eine konstante Referenz ist.