708 Stimmen

Was ist der Unterschied zwischen der Übergabe per Referenz und der Übergabe per Wert?

Was ist der Unterschied zwischen

  1. ein als Referenz übergebener Parameter
  2. einen als Wert übergebenen Parameter?

Könnten Sie mir bitte einige Beispiele nennen?

0 Stimmen

1 Stimmen

Wenn Sie nicht wissen, was ein Adresse o Wert ist dann siehe aquí

1257voto

Dylan Beattie Punkte 51678

Zuallererst, die Unterscheidung zwischen "Wertübergabe" und "Referenzübergabe", wie sie in der CS-Theorie definiert ist, ist jetzt überholt というのも die ursprünglich als "pass by reference" definierte Technik ist inzwischen in Vergessenheit geraten und wird nur noch selten verwendet. 1

Neuere Sprachen 2 tendieren dazu, ein anderes (aber ähnliches) Paar von Techniken zu verwenden, um die gleichen Effekte zu erzielen (siehe unten), die die Hauptquelle der Verwirrung ist.

Eine weitere Quelle der Verwirrung ist die Tatsache, dass in "pass by reference" hat der Begriff "Referenz" eine engere Bedeutung als der allgemeine Begriff "Referenz" (denn der Satz ist älter als der Begriff).


Die authentische Definition lautet also:

  • Wenn ein Parameter durch Referenz übergeben der Anrufer und der Angerufene dieselbe Variable verwenden für den Parameter. Wenn der Aufrufende die Parametervariable ändert, ist die Auswirkung für die Variable des Aufrufenden sichtbar.

  • Wenn ein Parameter nach Wert übergeben haben der Anrufer und der Angerufene zwei unabhängige Variablen mit demselben Wert. Wenn der Aufrufende die Parametervariable ändert, ist die Auswirkung für den Aufrufenden nicht sichtbar.

Folgende Punkte sind bei dieser Definition zu beachten:

  • "Variable" bedeutet hier die (lokale oder globale) Variable des Aufrufers selbst -- d.h. wenn ich eine lokale Variable per Referenz übergebe und ihr zuweise, ändere ich die Variable des Aufrufers selbst, nicht z.B. das, worauf sie zeigt, wenn es ein Zeiger ist.

    • Dies gilt heute als schlechte Praxis (als implizite Abhängigkeit). Als solches, Praktisch alle neueren Sprachen sind ausschließlich oder fast ausschließlich "pass-by-value". Pass-by-Reference wird heute vor allem in Form von "Output/Inout-Argumenten" in Sprachen verwendet, in denen eine Funktion nicht mehr als einen Wert zurückgeben kann.
  • Die Bedeutung von "Referenz" in "pass by reference" . Der Unterschied zum allgemeinen Begriff "Referenz" besteht darin, dass diese "Referenz" ist vorübergehend und implizit. Der Angerufene erhält im Wesentlichen folgende Informationen eine "Variable", die in gewisser Weise "dieselbe" ist wie die ursprüngliche Variable. Wie genau dieser Effekt erreicht wird, ist irrelevant (z.B. kann die Sprache auch einige Implementierungsdetails offenlegen - Adressen, Zeiger, Dereferenzierung - all dies ist irrelevant; wenn der Nettoeffekt dieser ist, ist es Pass-by-Reference).

In modernen Sprachen haben Variablen in der Regel einen "Referenztyp". (ein weiteres Konzept, das später als "pass by reference" erfunden wurde und von diesem inspiriert ist), d.h. die eigentlichen Objektdaten werden separat irgendwo gespeichert (normalerweise auf dem Heap), und es werden immer nur "Referenzen" auf sie in Variablen gehalten und als Parameter übergeben. 3

Die Übergabe einer solchen Referenz fällt unter "pass-by-value weil der Wert einer Variablen technisch gesehen der Verweis selbst und nicht das verwiesene Objekt ist. Wie auch immer, Der Nettoeffekt auf das Programm kann derselbe sein wie bei "pass-by-value" oder "pass-by-reference":

  • Wenn ein Verweis einfach aus einer Variablen des Aufrufers genommen und als Argument übergeben wird, hat dies die gleiche Wirkung wie die Weitergabe durch Verweis: Wenn das verwiesene Objekt mutiert in der aufgerufenen Datei, wird der Aufrufer die Änderung sehen.
    • Wenn eine Variable, die diese Referenz enthält, jedoch neu zugewiesen, wird sie aufhören, auf dieses Objekt zu zeigen, so dass alle weiteren Operationen auf diese Variable stattdessen das Objekt betreffen, auf das sie jetzt zeigt.
  • Um den gleichen Effekt wie bei pass-by-value zu erzielen, wird zu einem bestimmten Zeitpunkt eine Kopie des Objekts erstellt. Die Optionen umfassen:
    • Der Aufrufer kann einfach eine private Kopie vor dem Aufruf erstellen und dem Angerufenen stattdessen einen Verweis auf diese Kopie geben.
    • In einigen Sprachen sind einige Objekttypen "unveränderlich": Jede Operation, die den Wert zu ändern scheint, erzeugt in Wirklichkeit ein völlig neues Objekt, ohne das ursprüngliche zu beeinflussen. Die Übergabe eines Objekts eines solchen Typs als Argument hat also immer den Effekt einer Wertübergabe: Es wird automatisch eine Kopie für den Aufrufer erstellt, wenn dieser eine Änderung benötigt, und das Objekt des Aufrufers wird davon nie betroffen.
      • In funktionalen Sprachen, tous Objekte sind unveränderlich.

Wie Sie sehen können, Dieses Paar von Techniken ist fast dasselbe wie die in der Definition, nur mit einer indirekten Ebene: Ersetzen Sie einfach "Variable" durch "referenziertes Objekt".

Es gibt keine einheitliche Bezeichnung für sie, was zu verdrehten Erklärungen wie "call by value where the value is a reference" führt. Im Jahr 1975 schlug Barbara Liskov den Begriff " Aufruf durch gemeinsame Nutzung von Objekten " (oder manchmal auch nur "Call-by-Sharing"), obwohl es sich nie richtig durchgesetzt hat. Außerdem weist keiner der beiden Begriffe eine Parallele zu dem ursprünglichen Paar auf. Kein Wunder, dass die alten Begriffe in Ermangelung eines besseren Begriffs wiederverwendet wurden, was zu Verwirrung führte. 4

(Ich würde die Begriffe "neu" o "Indirektes" Pass-by-Value/Pass-by-Reference für die neuen Techniken).


ANMERKUNG : Diese Antwort lautete lange Zeit:

Angenommen, ich möchte eine Webseite mit Ihnen teilen. Wenn ich Ihnen die URL mitteile, übergebe ich durch eine Referenz weiter. Sie können diese URL verwenden, um dieselbe Webseite zu sehen, die ich sehen kann. Wenn diese Seite geändert wird, sehen wir beide die Änderungen. Wenn Sie die URL löschen, zerstören Sie nur den Verweis auf diese Seite Seite - Sie löschen nicht die Seite selbst.

Wenn ich die Seite ausdrucke und Ihnen den Ausdruck gebe, komme ich an Wert. Ihre Seite ist eine abgekoppelte Kopie des Originals. Sie sehen keine Sie sehen keine nachträglichen Änderungen, und alle Änderungen, die Sie vornehmen (z. B. auf Ihrem Ausdruck) werden nicht auf der Originalseite angezeigt. Wenn Sie den Ausdruck zerstören, haben Sie Ihre Kopie des Objekts tatsächlich zerstört. Objekts zerstört - die Original-Webseite bleibt jedoch intakt.

C'est meist richtig außer die engere Bedeutung von "Referenz" - sie ist sowohl temporär als auch implizit (das muss sie nicht, aber explizit und/oder persistent zu sein sind zusätzliche Merkmale, die nicht Teil der Semantik der Weitergabe von Referenzen sind, wie oben erläutert). Eine nähere Analogie wäre, Ihnen eine Kopie eines Dokuments zu geben und Sie nicht aufzufordern, das Original zu bearbeiten.


1 Sofern Sie nicht in Fortran oder Visual Basic programmieren, ist dies nicht das Standardverhalten, und in den meisten heute verwendeten Sprachen ist ein echter Call-by-Reference nicht einmal möglich.

2 Auch eine ganze Reihe älterer Modelle unterstützen es

3 In mehreren modernen Sprachen sind alle Typen Referenztypen. Dieser Ansatz wurde 1975 von der Sprache CLU eingeführt und wurde seitdem von vielen anderen Sprachen übernommen, darunter Python und Ruby. Und viele weitere Sprachen verwenden einen hybriden Ansatz, bei dem einige Typen "Werttypen" und andere "Referenztypen" sind - darunter C#, Java und JavaScript.

4 Es ist nichts Schlechtes daran, einen passenden alten Begriff zu recyceln <em>per se, </em>aber man muss irgendwie deutlich machen, welche Bedeutung jeweils verwendet wird. Wenn man das nicht tut, ist das genau das, was immer wieder für Verwirrung sorgt.

181voto

Es ist eine Möglichkeit, Argumente an Funktionen zu übergeben. Die Übergabe per Referenz bedeutet, dass der Parameter der aufgerufenen Funktion derselbe ist wie das übergebene Argument des Aufrufers (nicht der Wert, sondern die Identität - die Variable selbst). Übergabe per Wert bedeutet, dass der Parameter der aufgerufenen Funktion eine Kopie des vom Aufrufer übergebenen Arguments ist. Der Wert ist derselbe, aber die Identität - die Variable - ist anders. Änderungen an einem Parameter durch die aufgerufene Funktion ändern also in einem Fall das übergebene Argument und im anderen Fall nur den Wert des Parameters in der aufgerufenen Funktion (die nur eine Kopie ist). In aller Eile:

  • Java unterstützt nur die Übergabe nach Wert. Kopiert immer Argumente, auch wenn beim Kopieren eines Verweises auf ein Objekt der Parameter in der aufgerufenen Funktion auf dasselbe Objekt zeigt und Änderungen an diesem Objekt im Aufrufer zu sehen sind. Da dies verwirrend sein kann, aquí ist das, was Jon Skeet dazu zu sagen hat.
  • C# unterstützt die Übergabe nach Wert und die Übergabe nach Referenz (Schlüsselwort ref beim Aufrufer und bei der aufgerufenen Funktion verwendet). Jon Skeet hat auch eine schöne Erklärung dazu aquí .
  • C++ unterstützt Wertübergabe und Referenzübergabe (Referenzparametertyp, der bei der aufgerufenen Funktion verwendet wird). Eine Erklärung dazu finden Sie weiter unten.

Codes

Da meine Sprache C++ ist, werde ich diese hier verwenden

// passes a pointer (called reference in java) to an integer
void call_by_value(int *p) { // :1
    p = NULL;
}

// passes an integer
void call_by_value(int p) { // :2
    p = 42;
}

// passes an integer by reference
void call_by_reference(int & p) { // :3
    p = 42;
}

// this is the java style of passing references. NULL is called "null" there.
void call_by_value_special(int *p) { // :4
    *p = 10; // changes what p points to ("what p references" in java)
    // only changes the value of the parameter, but *not* of 
    // the argument passed by the caller. thus it's pass-by-value:
    p = NULL;
}

int main() {
    int value = 10;
    int * pointer = &value;

    call_by_value(pointer); // :1
    assert(pointer == &value); // pointer was copied

    call_by_value(value); // :2
    assert(value == 10); // value was copied

    call_by_reference(value); // :3
    assert(value == 42); // value was passed by reference

    call_by_value_special(pointer); // :4
    // pointer was copied but what pointer references was changed.
    assert(value == 10 && pointer == &value);
}

Und ein Beispiel in Java kann auch nicht schaden:

class Example {
    int value = 0;

    // similar to :4 case in the c++ example
    static void accept_reference(Example e) { // :1
        e.value++; // will change the referenced object
        e = null; // will only change the parameter
    }

    // similar to the :2 case in the c++ example
    static void accept_primitive(int v) { // :2
        v++; // will only change the parameter
    }        

    public static void main(String... args) {
        int value = 0;
        Example ref = new Example(); // reference

        // note what we pass is the reference, not the object. we can't 
        // pass objects. The reference is copied (pass-by-value).
        accept_reference(ref); // :1
        assert ref != null && ref.value == 1;

        // the primitive int variable is copied
        accept_primitive(value); // :2
        assert value == 0;
    }
}

Wikipedia

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_value

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_reference

Dieser Typ bringt es ziemlich genau auf den Punkt:

http://javadude.com/articles/passbyvalue.htm

127voto

Daniel Pryden Punkte 56882

Viele Antworten hier (und insbesondere die am meisten hochgestimmte Antwort) sind sachlich falsch, da sie missverstehen, was "call by reference" wirklich bedeutet. Hier ist mein Versuch, die Dinge richtig zu stellen.

TL;DR

Vereinfacht ausgedrückt:

  • Aufruf nach Wert bedeutet, dass Sie die Werte als Funktionsargumente
  • Referenzaufruf bedeutet, dass Sie die Variablen als Funktionsargumente

Um es metaphorisch auszudrücken:

  • Aufruf nach Wert ist, wo Ich schreibe etwas auf ein Blatt Papier und gebe es Ihnen . Vielleicht ist es eine URL, vielleicht ist es eine vollständige Kopie von Krieg und Frieden. Egal, was es ist, es steht auf einem Stück Papier, das ich Ihnen gegeben habe, und so ist es jetzt effektiv Ihr Blatt Papier . Sie können nun auf diesem Blatt Papier herumkritzeln oder dieses Blatt Papier benutzen, um irgendwo anders etwas zu finden und daran herumzufummeln, was auch immer.
  • Aufruf durch Verweis ist, wenn Ich gebe Ihnen mein Notizbuch, in das ich etwas hineingeschrieben habe . Du darfst in mein Notizbuch kritzeln (vielleicht will ich das, vielleicht auch nicht), und danach behalte ich mein Notizbuch, mit allem, was du hineingekritzelt hast. Und wenn das, was Sie oder ich dort geschrieben haben, Informationen darüber sind, wie man etwas anderswo findet, können Sie oder ich dorthin gehen und diese Informationen bearbeiten.

Was bedeuten "Aufruf durch Wert" und "Aufruf durch Verweis"? nicht mittlere

Beachten Sie, dass diese beiden Konzepte völlig unabhängig und orthogonal zum Konzept der Referenztypen (das sind in Java alle Typen, die Untertypen von Object und in C# alle class Typen), oder das Konzept der Zeigertypen wie in C (die semantisch äquivalent zu den "Referenztypen" von Java sind, nur mit einer anderen Syntax).

Der Begriff der Referenztyp entspricht einer URL: Sie ist sowohl selbst eine Information als auch ein Referenz (a Zeiger (wenn Sie so wollen) zu anderen Informationen. Sie können viele Kopien einer URL an verschiedenen Orten haben, ohne dass sich die Website ändert, auf die sie alle verweisen; wenn die Website aktualisiert wird, führt jede URL-Kopie weiterhin zu den aktualisierten Informationen. Umgekehrt wirkt sich eine Änderung der URL an einer Stelle nicht auf die anderen Kopien der URL aus.

Beachten Sie, dass C++ einen Begriff von "Referenzen" hat (z.B.. int& ), das ist pas wie die "Referenztypen" von Java und C#, aber es wie "Aufruf durch Referenz". Die "Referenztypen" von Java und C# und tous Typen in Python sind wie das, was in C und C++ "Zeigertypen" genannt wird (z. B. int* ).


OK, hier ist die längere und formellere Erklärung.

Terminologie

Zunächst möchte ich einige wichtige Begriffe hervorheben, um meine Antwort zu verdeutlichen und um sicherzustellen, dass wir uns alle auf die gleichen Begriffe beziehen, wenn wir sie verwenden. (In der Praxis glaube ich, dass die überwiegende Mehrheit der Verwirrung bei Themen wie diesen darauf zurückzuführen ist, dass Wörter so verwendet werden, dass sie die beabsichtigte Bedeutung nicht vollständig vermitteln).

Zunächst ein Beispiel für eine Funktionsdeklaration in einer C-ähnlichen Sprache:

void foo(int param) {  // line 1
  param += 1;
}

Und hier ist ein Beispiel für den Aufruf dieser Funktion:

void bar() {
  int arg = 1;  // line 2
  foo(arg);     // line 3
}

Anhand dieses Beispiels möchte ich einige wichtige Begrifflichkeiten definieren:

  • foo ist eine Funktion deklariert in Zeile 1 (Java besteht darauf, alle Funktionen zu Methoden zu machen, aber das Konzept ist dasselbe, ohne Verlust der Allgemeinheit; C und C++ unterscheiden zwischen Deklaration und Definition, auf die ich hier nicht eingehen werde)
  • param ist eine Formalparameter a foo auch in Zeile 1 angegeben
  • arg ist eine variabel insbesondere eine lokale Variable der Funktion bar , deklariert und initialisiert in Zeile 2
  • arg ist auch ein Argument zu einer bestimmten Aufruf von foo in Zeile 3

Hier sind zwei sehr wichtige Begriffspaare zu unterscheiden. Der erste ist Wert gegen variabel :

  • A Wert ist die Ergebnis der Auswertung eines Ausdrucks in der Sprache. Zum Beispiel, in der bar Funktion, nach der Zeile int arg = 1; ist der Ausdruck arg hat die Wert 1 .
  • A variabel ist eine Container für Werte . Eine Variable kann veränderbar sein (dies ist der Standard in den meisten C-ähnlichen Sprachen), schreibgeschützt (z. B. deklariert mit Javas final oder C#s readonly ) oder tief unveränderlich (z.B. mit C++'s const ).

Das andere wichtige Begriffspaar, das es zu unterscheiden gilt, ist Parameter gegen Argument :

  • A Parameter (auch genannt Formalparameter ) ist eine variabel die vom Aufrufer beim Aufruf einer Funktion angegeben werden muss.
  • Eine Argument ist eine Wert die vom Aufrufer einer Funktion geliefert wird, um einen bestimmten formalen Parameter dieser Funktion zu erfüllen

Aufruf nach Wert

En Aufruf nach Wert Bei den formalen Parametern der Funktion handelt es sich um Variablen, die für den Funktionsaufruf neu angelegt und mit der Option Werte ihrer Argumente.

Dies funktioniert genau so, wie alle anderen Arten von Variablen mit Werten initialisiert werden. Zum Beispiel:

int arg = 1;
int another_variable = arg;

Hier arg y another_variable sind völlig unabhängige Variablen - ihre Werte können sich unabhängig voneinander ändern. An dem Punkt jedoch, an dem another_variable deklariert wird, wird es mit demselben Wert initialisiert, den arg hält - und das ist 1 .

Da es sich um unabhängige Variablen handelt, sind Änderungen der another_variable nicht beeinflussen arg :

int arg = 1;
int another_variable = arg;
another_variable = 2;

assert arg == 1; // true
assert another_variable == 2; // true

Dies ist genau dasselbe wie die Beziehung zwischen arg y param in unserem obigen Beispiel, das ich hier aus Gründen der Symmetrie wiederholen möchte:

void foo(int param) {
  param += 1;
}

void bar() {
  int arg = 1;
  foo(arg);
}

Es ist genau so, als hätten wir den Code auf diese Weise geschrieben:

// entering function "bar" here
int arg = 1;
// entering function "foo" here
int param = arg;
param += 1;
// exiting function "foo" here
// exiting function "bar" here

Das heißt, das entscheidende Merkmal dessen, was Aufruf nach Wert bedeutet, dass der Angerufene ( foo in diesem Fall) erhält Werte als Argumente, hat aber seine eigene separate Variablen für diese Werte aus den Variablen des Aufrufers ( bar in diesem Fall).

Um auf meine obige Metapher zurückzukommen: Wenn ich bar und Sie sind foo Wenn ich Sie anrufe, gebe ich Ihnen einen Zettel mit einer Wert darauf geschrieben. Sie nennen das Stück Papier param . Dieser Wert ist ein kopieren. des Wertes, den ich in mein Notizbuch geschrieben habe (meine lokalen Variablen), in eine Variable, die ich arg .

(Nebenbei bemerkt: Je nach Hardware und Betriebssystem gibt es verschiedene Namenskonventionen darüber, wie man eine Funktion von einer anderen aus aufruft. Die Aufrufkonvention ist so, als ob wir uns entscheiden, ob ich den Wert auf ein Blatt Papier schreibe und es Ihnen dann gebe, oder ob Sie ein Blatt Papier haben, auf das ich es schreibe, oder ob ich es vor uns beiden an die Wand schreibe. Auch das ist ein interessantes Thema, würde aber den Rahmen dieser ohnehin schon langen Antwort bei weitem sprengen).

Aufruf durch Verweis

En Referenzaufruf sind die formalen Parameter der Funktion einfach neue Namen für die gleichen Variablen, die der Aufrufer als Argumente liefert.

Um auf unser obiges Beispiel zurückzukommen, ist das gleichbedeutend mit:

// entering function "bar" here
int arg = 1;
// entering function "foo" here
// aha! I note that "param" is just another name for "arg"
arg /* param */ += 1;
// exiting function "foo" here
// exiting function "bar" here

Desde param ist nur ein anderer Name für arg -- das heißt, sie sind die gleiche Variable , Änderungen an param spiegeln sich wider in arg . Dies ist der grundlegende Unterschied zwischen dem Aufruf über eine Referenz und dem Aufruf über einen Wert.

Nur sehr wenige Sprachen unterstützen den Aufruf per Verweis, aber C++ kann dies auf diese Weise tun:

void foo(int& param) {
  param += 1;
}

void bar() {
  int arg = 1;
  foo(arg);
}

In diesem Fall, param hat nicht nur die gleichen Wert als arg ist es tatsächlich es arg (nur unter einem anderen Namen) und so bar kann feststellen, dass arg wurde inkrementiert.

Beachten Sie, dass es sich hierbei um pas wie Java, JavaScript, C, Objective-C, Python oder fast alle anderen heute gängigen Sprachen funktionieren. Das bedeutet, dass diese Sprachen pas Aufruf durch Verweis, sie sind Aufruf durch Wert.

Nachtrag: Aufruf durch gemeinsame Nutzung von Objekten

Wenn Sie Folgendes haben Aufruf nach Wert , aber der tatsächliche Wert ist a Referenztyp o Zeigertyp ist der "Wert" selbst nicht sehr interessant (in C ist er z.B. nur eine ganze Zahl mit einer plattformspezifischen Größe) - interessant ist, was dieser Wert zeigt auf .

Wenn der Referenztyp (d. h. der Zeiger) auf Folgendes verweist änderbar ist ein interessanter Effekt möglich: Sie können den Wert, auf den der Zeiger zeigt, ändern, und der Aufrufer kann Änderungen am Wert, auf den der Zeiger zeigt, beobachten, obwohl der Aufrufer Änderungen am Zeiger selbst nicht beobachten kann.

Um noch einmal die Analogie der URL zu bemühen: Die Tatsache, dass ich Ihnen eine kopieren. der URL einer Website ist nicht sonderlich interessant, wenn wir uns beide für die Website und nicht für die URL interessieren. Die Tatsache, dass Sie Ihre Kopie der URL überschreiben, hat keinen Einfluss auf meine Kopie der URL (und in Sprachen wie Java und Python kann die "URL" oder der Wert des Referenztyps überhaupt nicht geändert werden, sondern nur das, worauf sie verweist).

Als Barbara Liskov die CLU-Programmiersprache erfand (die diese Semantik hatte), erkannte sie, dass die bestehenden Begriffe "call by value" und "call by reference" nicht besonders nützlich waren, um die Semantik dieser neuen Sprache zu beschreiben. Also erfand sie einen neuen Begriff: Aufruf durch gemeinsame Nutzung von Objekten .

Wenn man über Sprachen spricht, die zwar technisch gesehen "call by value" sind, in denen aber üblicherweise Referenz- oder Zeigertypen verwendet werden (d.h. fast jede moderne imperative, objektorientierte oder multiparadigmatische Programmiersprache), finde ich es viel weniger verwirrend, wenn man es einfach vermeidet, über Aufruf nach Wert o Referenzaufruf . Einhalten Aufruf durch gemeinsame Nutzung von Objekten (oder einfach Aufruf durch Objekt ) und niemand wird verwirrt sein :-)

77voto

mfaani Punkte 28161

Bevor Sie diese beiden Begriffe verstehen, sollten Sie muss das Folgende verstehen. Jedes Objekt hat zwei Dinge, die es unterscheidbar machen können.

  • Sein Wert.
  • Seine Adresse.

Wenn Sie also sagen employee.name = "John" wissen, dass es zwei Dinge gibt, die name . Sein Wert, der "John" und auch seine Position im Speicher, die eine hexadezimale Zahl ist, vielleicht wie diese: 0x7fd5d258dd00 .

Abhängig von der Architektur der Sprache oder der Typ (Klasse, Struktur, usw.) Ihres Objekts, würden Sie entweder "John" o 0x7fd5d258dd00

Weitergabe "John" ist als Übergabe nach Wert bekannt.

Weitergabe 0x7fd5d258dd00 ist als Übergabe durch Verweis bekannt. Jeder, der auf diesen Speicherplatz verweist, hat Zugriff auf den Wert von "John" .

Für weitere Informationen hierzu empfehle ich Ihnen die Lektüre von Dereferenzierung eines Zeigers und auch Warum sollte man struct (Werttyp) einer Klasse (Referenztyp) vorziehen? .

55voto

pyon Punkte 18048

Hier ist ein Beispiel:

#include <iostream>

void by_val(int arg) { arg += 2; }
void by_ref(int&arg) { arg += 2; }

int main()
{
    int x = 0;
    by_val(x); std::cout << x << std::endl;  // prints 0
    by_ref(x); std::cout << x << std::endl;  // prints 2

    int y = 0;
    by_ref(y); std::cout << y << std::endl;  // prints 2
    by_val(y); std::cout << y << std::endl;  // prints 2
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X