2010-11-18 7 views
1

Wenn Wertaufruf verwendet wird, werden die tatsächlichen Parameterwerte in den Stapel geschoben. Was ist mit Anruf per Referenz? Was wird auf den Call-Stack geschoben?Wenn Wertaufruf verwendet wird, werden die tatsächlichen Parameterwerte in den Stapel geschoben. Was ist mit Anruf per Referenz?

EDIT:

Schön, dass Java nicht zu wissen, call by reference nicht verwendet, immer. Wie wäre es in C++? Ich habe das Tag von Java in C++ geändert. Entschuldigung für die Verwirrung.

+0

Ist es die Referenzadresse? – kiraj

+0

Wie verhält es sich mit Java? – jjnguy

+0

Ich habe ein paar Spam-Haiku bekommen, als ich versucht habe, die Frage zu stellen. Ich habe vergessen, es als C++ zu markieren. – kiraj

Antwort

2

Es gibt keinen Aufruf durch Referenz in Java. Alles ist Ruf nach Wert.

Von Is Java "pass-by-reference" or "pass-by-value"?

Java ist immer pass-by-Wert. Die schwierige Sache kann sein, zu verstehen, dass Java Objekte als Referenzen übergibt, die nach Wert übergeben werden.

Von http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

Java funktioniert durch Referenzobjekte manipulieren und alle Objektvariablen Referenzen sind. Java übergibt jedoch keine Methodenargumente als Referenz. es übergibt sie nach Wert.

Weitere Informationen finden Sie unter this answer.

Was ist mit Anruf per Referenz? Was wird auf den Call-Stack geschoben?

Dann wird die Referenz auf den Operandenstapel geschoben.

+0

Schöne Antwort, obwohl die Frage für C++ und nicht Java war. – Anthony

+1

uhm, die Frage wurde mit Java getaggt, als ich antwortete: - / – aioobe

0

Was meinen Sie "wenn Call by Value verwendet wird"? Java ist immer Aufruf nach Wert, außer dass die meisten Werte Objektreferenzen sind. Aber es gibt kein "wenn" oder "wann", es funktioniert immer gleich.

Also ja, auf Bytecodeebene werden die Referenzen selbst auf den Stack geschoben. Was diese enthalten, ist bis zur JVM-Implementierung (I denken), aber es ist fast sicher, dass sie Speicheradressen sind.

0

In C++ wird die Adresse der Variablen auf den Stapel geschoben, wenn Call-Referenz verwendet wird. Dadurch wird eine neue Objekterstellung eliminiert und alle Änderungen, die Sie in der Anforderungsfunktion vornehmen, sind im Aufrufer verfügbar.

0

Es hängt von der C++ - Implementierung ab. Vielleicht werden Referenzen nur als Zeiger übergeben. Vielleicht werden sie anstelle des Stapels in Register eingetragen. Vielleicht existiert ein Stack gar nicht. Die C++ - Sprache schreibt keines dieser Dinge vor.

Zusätzlich, wie die Dinge übergeben (auch bekannt als die „Aufrufkonvention“) können innerhalb der gleichen Implementierung unterschiedlich sein. Zum Beispiel, wenn eine Funktion inline ist, könnten die Referenten einfach direkt anstelle der obigen Möglichkeiten verwendet werden. Viele Implementierungen bieten Erweiterungen, mit denen Sie die Aufrufkonvention angeben können (z. B. __fastcall unter Windows).

0

Die Referenz ist ein "Spezialzeiger". Es ist die Adresse eines physikalischen Objekts.Der wichtige Unterschied zwischen Referenz und Zeiger sind zwei:

1) Die Referenz kann nicht null sein und muss immer auf ein vorhandenes Objekt zeigen.

2) Sie können einen Verweis auf ein anderes Objekt nicht neu zuweisen.

Auch die Referenz und das Objekt verwenden die gleiche Syntax "." statt "->".

Die Referenz ist sehr gut, weil Sie vermeiden können, ein temporäres Objekt zu erstellen (zum Beispiel in einem Funktionsaufruf).

zurück zu Ihrer Frage: Was wird auf den Call-Stack geschoben?

Die Adresse des Objekts, auf das durch die Referenz verwiesen wird.

0

Es könnte compilerabhängig sein, aber g ++ setzt die Adresse der Variable auf den Stack. Dies wird durch eine Demontage des Code dargestellt:

void func_by_ref(int& i) { 
    i = 2; 
} 

(gdb) disas func_by_ref 
Dump of assembler code for function _Z11func_by_refRi: 
    0x080486b0 <+0>:  push %ebp 
    0x080486b1 <+1>:  mov %esp,%ebp 
    0x080486b3 <+3>:  mov 0x8(%ebp),%eax 
    0x080486b6 <+6>:  movl $0x2,(%eax) 
    0x080486bc <+12>: pop %ebp 
    0x080486bd <+13>: ret 
End of assembler dump. 

Dies ist identisch zu erzeugende Code, wenn ein Zeiger Parameter verwendet, wie

void func_by_pointer(int* i) { 
    *i = 2; 
} 
Verwandte Themen