Pass by Reference / Value in C++

Lesezeit: 7 Minuten

Pass by Reference Value in C
Benutzer36064

Ich möchte die Unterschiede zwischen nach Wert und nach Referenz verdeutlichen.

Ich habe ein Bild gemalt

Geben Sie hier die Bildbeschreibung ein

Also, um den Wert zu übergeben,

Eine Kopie eines identischen Objekts wird mit einer anderen Referenz erstellt, und der lokalen Variablen wird die neue Referenz zugewiesen, um auf die neue Kopie zu zeigen

Wie sind die Worte zu verstehen: ” Wenn die Funktion diesen Wert ändert, erscheinen die Änderungen auch im Bereich der aufrufenden Funktion, sowohl für die Übergabe als Wert als auch als Referenz “

Danke!

1647173410 782 Pass by Reference Value in C
Johannes Schaub – litb

Ich denke, dass viel Verwirrung entsteht, wenn man nicht kommuniziert, was gemeint ist per Referenz übergeben. Wenn manche Leute sagen als Referenz übergeben sie meinen normalerweise nicht das Argument selbst, sondern vielmehr das Objekt, auf das verwiesen wird. Einige andere sagen, dass die Übergabe als Referenz bedeutet, dass das Objekt im Aufgerufenen nicht geändert werden kann. Beispiel:

struct Object {
    int i;
};

void sample(Object* o) { // 1
    o->i++;
}

void sample(Object const& o) { // 2
    // nothing useful here :)
}

void sample(Object & o) { // 3
    o.i++;
}

void sample1(Object o) { // 4
    o.i++;
}

int main() {
    Object obj = { 10 };
    Object const obj_c = { 10 };

    sample(&obj); // calls 1
    sample(obj) // calls 3
    sample(obj_c); // calls 2
    sample1(obj); // calls 4
}

Einige Leute würden behaupten, dass 1 und 3 als Referenz übergeben werden, während 2 als Wert übergeben wird. Eine andere Gruppe von Leuten sagt, dass alles bis auf das letzte als Referenz übergeben wird, weil das Objekt selbst nicht kopiert wird.

Ich möchte hier eine Definition dessen ziehen, was ich zu sein behaupte als Referenz übergeben. Eine allgemeine Übersicht darüber finden Sie hier: Unterschied zwischen Pass-by-Reference und Pass-by-Value. Der erste und der letzte werden als Wert übergeben, und die beiden mittleren werden als Referenz übergeben:

    sample(&obj);
       // yields a `Object*`. Passes a *pointer* to the object by value. 
       // The caller can change the pointer (the parameter), but that 
       // won't change the temporary pointer created on the call side (the argument). 

    sample(obj)
       // passes the object by *reference*. It denotes the object itself. The callee
       // has got a reference parameter.

    sample(obj_c);
       // also passes *by reference*. the reference parameter references the
       // same object like the argument expression. 

    sample1(obj);
       // pass by value. The parameter object denotes a different object than the 
       // one passed in.

Ich stimme für folgende Definition:

Ein Argument (1.3.1) wird genau dann als Referenz übergeben, wenn der entsprechende Parameter der aufgerufenen Funktion vom Typ Referenz ist und der Referenzparameter bindet direkt an den Argumentausdruck (8.5.3/4). In allen anderen Fällen haben wir es mit Wertübergabe zu tun.

Das bedeutet, dass Folgendes als Wert übergeben wird:

void f1(Object const& o);
f1(Object()); // 1

void f2(int const& i);
f2(42); // 2

void f3(Object o);
f3(Object());     // 3
Object o1; f3(o1); // 4

void f4(Object *o);
Object o1; f4(&o1); // 5

1 wird als Wert übergeben, da es nicht direkt gebunden ist. Die Implementierung kann das Temporäre kopieren und dieses Temporäre dann an die Referenz binden. 2 wird als Wert übergeben, da die Implementierung ein temporäres des Literals initialisiert und dann an die Referenz bindet. 3 wird als Wert übergeben, da der Parameter keinen Referenztyp hat. 4 wird aus dem gleichen Grund als Wert übergeben. 5 wird als Wert übergeben, da der Parameter keinen Referenztyp hat. Die folgenden Fälle werden als Referenz übergeben (durch die Regeln von 8.5.3/4 und andere):

void f1(Object *& op);
Object a; Object *op1 = &a; f1(op1); // 1

void f2(Object const& op);
Object b; f2(b); // 2

struct A { };
struct B { operator A&() { static A a; return a; } };
void f3(A &);
B b; f3(b); // passes the static a by reference

  • Können Sie erklären, dass “der Referenzparameter direkt an den Argumentausdruck gebunden ist”?

    – jaraaj

    8. Januar 2009 um 11:30 Uhr

  • Wenn das Argument nicht denselben Typ hat oder keine abgeleitete Klasse des Parameters ist und keinen Konvertierungsoperator für den Typ des Parameters hat, dann hat der Argumentausdruck dies nicht direkt an den Referenzparameter binden.

    – Johannes Schaub – litb

    8. Januar 2009 um 11:37 Uhr

  • auch wenn das Argument ein rvalue ist (wie das Integer-Literal 42 im Beispiel). Die genaue Definition finden Sie in der Norm

    – Johannes Schaub – litb

    8. Januar 2009 um 11:39 Uhr

  • in “void f1(Object const& o); f1(Object());” Warum darf das Impl das Temporäre kopieren?

    Iraimbilanja

    8. Januar 2009 um 17:36 Uhr

  • Iraimbilanja, weil der Standard das sagt (lesen Sie 8.5.3p5). Die Implementierung darf eine Kopie erstellen, tut es aber nicht verfügen über das zu tun. in der Tat, wenn der rvalue (das Objekt ()) an den Kopierkonstruktor von Object übergeben wird, darf dies nicht geschehen, um eine unendliche Rekursion zu verhindern (es müsste erneut kopiert werden: p).

    – Johannes Schaub – litb

    8. Januar 2009 um 18:33 Uhr

Pass by Reference Value in C
Flamme

Bei Wertübergabe:

void func(Object o);

und dann anrufen

func(a);

Sie werden eine konstruieren Object auf dem Stack und innerhalb der Implementierung von func es wird von referenziert o. Dies könnte immer noch eine flache Kopie sein (die Interna von a und o könnte auf dieselben Daten verweisen), so a könnte geändert werden. Wie auch immer, falls o ist eine tiefe Kopie von adann a wird sich nicht ändern.

Bei Referenzübergabe:

void func2(Object& o);

und dann anrufen

func2(a);

Sie geben nur eine neue Art der Referenz an a. “a” und “o” sind zwei Namen für dasselbe Objekt. Ändern o Innerhalb func2 macht diese Änderungen für den Aufrufer sichtbar, der das Objekt unter dem Namen “a“.

Vielen Dank an alle für all diese Beiträge!

Ich habe diesen Satz aus einer Vorlesungsnotiz im Internet zitiert:
http://www.cs.cornell.edu/courses/cs213/2002fa/lectures/Lecture02/Lecture02.pdf

die erste Seite die 6. Folie

” Pass by VALUE Der Wert einer Variablen wird an die Funktion übergeben. Wenn die Funktion diesen Wert ändert, bleiben die Änderungen im Bereich dieser Funktion.

Übergabe an REFERENCE Eine Referenz auf die Variable wird an die Funktion weitergegeben. Wenn die Funktion diesen Wert ändert, erscheinen die Änderungen auch im Bereich der aufrufenden Funktion.

Nochmals vielen Dank!

  • Als Anfänger in C++ finde ich das nützlich, obwohl dieser Beitrag vor einiger Zeit gepostet wurde. Danke.

    – Richard Atterfalk

    8. Juni 2014 um 6:25 Uhr

Ich bin mir nicht sicher, ob ich deine Frage richtig verstehe. Es ist etwas unklar. Was Sie jedoch verwirren könnte, ist Folgendes:

  1. Bei der Übergabe per Referenz wird eine Referenz auf dasselbe Objekt an die aufgerufene Funktion übergeben. Alle Änderungen am Objekt werden im ursprünglichen Objekt widergespiegelt und daher wird der Aufrufer es sehen.

  2. Bei der Wertübergabe wird der Kopierkonstruktor aufgerufen. Der standardmäßige Kopierkonstruktor führt nur eine flache Kopie aus. Wenn die aufgerufene Funktion eine Ganzzahl im Objekt ändert, wird dies von der aufrufenden Funktion nicht gesehen, aber wenn die Funktion eine Datenstruktur ändert, auf die ein Zeiger innerhalb des Objekts zeigt , dann wird dies vom Aufrufer aufgrund der flachen Kopie gesehen.

Ich habe deine Frage vielleicht falsch verstanden, aber ich dachte, ich würde es trotzdem versuchen.

Wie ich es analysiere, sind diese Wörter falsch. Es sollte lauten “Wenn die Funktion diesen Wert ändert, erscheinen die Änderungen auch im Bereich der aufrufenden Funktion, wenn sie als Referenz übergeben werden, aber nicht, wenn sie als Wert übergeben werden.”

Pass by Reference Value in C
jwpfox

Mein Verständnis der Worte “Wenn die Funktion diesen Wert ändert, erscheinen die Änderungen auch im Bereich der aufrufenden Funktion sowohl für die Übergabe als Wert als auch als Referenz” ist, dass sie es sind ein Fehler.

Änderungen, die in einer aufgerufenen Funktion vorgenommen werden, sind nicht im Geltungsbereich der aufrufenden Funktion bei Wertübergabe.

Entweder haben Sie sich bei den zitierten Wörtern vertippt oder sie wurden aus dem Kontext herausgezogen, was falsch erscheint, richtig.

Könnten Sie bitte sicherstellen, dass Sie Ihre Quelle korrekt zitiert haben, und wenn es keine Fehler gibt, geben Sie mehr Text rund um diese Aussage im Quellenmaterial an.

997530cookie-checkPass by Reference / Value in C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy