Dereferenziert ein Zeiger und übergibt das an eine Funktion, die sein Argument durch Verweis annimmt, eine Kopie des Objekts erstellen?Macht die Dereferenzierung eines Zeigers eine Kopie davon?
Antwort
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.
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. –
@Sergey: Gute Punkte, die sehr schlecht formuliert wurde :) – Goz
Ich schrieb ein einfaches Testprogramm, um die Antworten für mich selbst zu überprüfen, hoffentlich hilft das einige http://codepad.org/XDqahndf – RishiD
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 1
weilinc
nimmt ihr Argument durch Bezugnahme zu drucken. Wäre eine Kopie unter inc
Aufruf erstellt worden, würde der Code 0
drucken.
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.
"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. –
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. –
@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. –
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.
Re: der Titel. Wenn der Dereferenzierung eines Zeigers eine Kopie des Objekts erstellt würde, wäre es nicht unmöglich, das Objekt jemals zu verwenden ?! – visitor