Das ist das Ende von C++!
-
Optimizer schrieb:
Jester schrieb:
Ich finde aber auch, dass einen Pointer in C++ zu übergeben ein Call by reference ist.
Gut, von dem Standpunkt aus kann ich das begrenzt nachvollziehen, weil du einfach immer an das referenzierte Objekt denkst. Richtig glücklich würde ich selber mit dieser Sichtweise nicht werden.
Call by reference/value unterscheidet sich für mich nicht im Variablentyp, sondern in der Semantik des Aufrufs und im Funktionsrumpf ist das transparent. Also man macht irgendwas mit dem Parameter und je nachdem ob man im Kopf value oder ref ausgewählt hat, wirkt sich das außerhalb aus oder nicht. In C++ würde das im Kopf durch T bzw. T& dargestellt werden und es ist auch genau so, dass es im Rumpf dann gar nicht mehr erkennbar ist, was es ist. In C# würde es T oder ref T heißen. In Java gibt es das halt nicht.
In Java interessieren mich im Allgemeinen nicht die Pointer (wie Simon sagte - "es gibt keine Pointer"), sondern die dahinterliegenden Objekte - wie diese (semantisch) übergeben werden, kann nicht vom Programmierer beeinflusst werden: primitive Typen werden immer per-value übergeben, eigene Typen immer per-ref.
(und wer aus irgendeinem Grund etwas anderes braucht, muß sich schon sehr verrenken)In C gibt es technisch auch nur eine Übergabe-Methode - per-value. Allerdings kann man da selber entscheiden, ob man da ein Objekt oder einen Zeiger auf ein Objekt (womit man doch wieder eine per-ref Semantik nachbauen kann) übergeben will. C++ baut auf diesem Konzept auf und bietet als Erweiterung Referenzen (quasi als selbst-dereferenzierende Pointer). Auf jeden Fall kannst du - unabhängig von der Art der verwendeten Daten - selber entscheiden, ob du Value-Semantik oder Referenz-Semantik anbieten willst.
-
Optimizer schrieb:
In C# würde es T oder ref T heißen.
In C# muss du nur Werttype als ref übergeben, sonst auch nicht.
-
Zeus schrieb:
...
Hmm Call-by-Value ohne was zu Hand zu machen, oder hassu von Java gesprochen?
Weder noch: Nur vertippt.
Gruß,
Simon2.
-
Optimizer schrieb:
...
Naja es ist doch in Java immer by value. Wenn du einen Zeiger übergibst, wird der Zeiger kopiert. ...Also eine kleine (natürlich nicht wirklich repräsentative) Mittagsumfrage unter den jahrelangen Java-Programmierern (selbst denen, die nie was anderes programmiert haben) hat ergeben, dass nicht einer Java call-by-value-Semantik zuschreibt (Ausnahme: primitive Typen).
Nochmal die Frage: Was ist denn dann ein "call-by-reference" (wenn nicht der, bei dem statt eines Objekts eine Referenz darauf übergeben wird) ?Ehrlich gesagt, ist mir noch NIE Deine Standpunkt vorher untergekommen ... und es ist mit gut 600 Entwicklern doch ein recht großes Softwarehaus, in dem ich arbeite.
... und letzlich stimmt ja einfach Folgendes nicht:
Optimizer schrieb:
...
...In Java muss halt einem klar sein, dass man grundsätzlich nur Objektzeiger in der Hand hat....nämlich: Für primitive Typen. (und darum geht es)
Gruß,
Simon2.
-
Auf jeden Fall kannst du - unabhängig von der Art der verwendeten Daten - selber entscheiden, ob du Value-Semantik oder Referenz-Semantik anbieten willst.
Nein, das stimmt auch (glücklicherweise) in C++ so nicht. Die Entscheidung welche Übergabe Sinn macht, liegt ganz klar beim Entwickler des Datentyps, da nur dieser weiß ob eine Kopie überhaupt Sinn macht. Java und C++ haben einfach nur einen anderen Ausgangsstandpunkt, oder sozusagen eine andere "Default-Policy". C++ Entwickler haben mit dem Copy Constructor die Möglichkeit Kopien zu verhindern, während Java Entwickler diese erst durch eine Clone-Implementierung erlauben müssen.
-
quote experte schrieb:
Auf jeden Fall kannst du - unabhängig von der Art der verwendeten Daten - selber entscheiden, ob du Value-Semantik oder Referenz-Semantik anbieten willst.
Nein, das stimmt auch (glücklicherweise) in C++ so nicht. Die Entscheidung welche Übergabe Sinn macht, liegt ganz klar beim Entwickler des Datentyps, da nur dieser weiß ob eine Kopie überhaupt Sinn macht. Java und C++ haben einfach nur einen anderen Ausgangsstandpunkt, oder sozusagen eine andere "Default-Policy". C++ Entwickler haben mit dem Copy Constructor die Möglichkeit Kopien zu verhindern, während Java Entwickler diese erst durch eine Clone-Implementierung erlauben müssen.
Hmmm, 3 Fragen zu meinem Verständnis:
- aber ich kann doch als Entwickler der aufgerufenen Funktion das Verhalten weder automatisiert, noch in der Signatur festlegen, oder ?
- D.h. ich muß jedesmal per Hand "clonen" (auch auf die Gefahr hin, dass der Aufrufer das für mich schon getan hat) .... und dem Aufrufer das auch nur via "Doku" mitteilen, oder ?
- Und selbst wenn ich den call-by-val für Klassentypen implementieren kann, bleibt mir der call-by-ref für primitive Typen unmöglich, oder ?
- Sehe ich das richtig, dass Du auch der Meinung bist, der "normale Call" in Java sei call-by-ref ?
Gruß,
Simon2.
-
Simon2 schrieb:
Also eine kleine (natürlich nicht wirklich repräsentative) Mittagsumfrage unter den jahrelangen Java-Programmierern (selbst denen, die nie was anderes programmiert haben)
Irrelevant, gerade die Meinung derer, die noch nie etwas anderes programmiert haben. In der täglichen Programmierpraxis ist diese Frage nämlich normalerweise überhaupt nicht von Belang. Es sei denn ihr entwickelt Java-Compiler o.ä.
hat ergeben, dass nicht einer Java call-by-value-Semantik zuschreibt (Ausnahme: primitive Typen).
Nochmal die Frage: Was ist denn dann ein "call-by-reference" (wenn nicht der, bei dem statt eines Objekts eine Referenz darauf übergeben wird) ?Call-by-xyz heißt, dass die Übergabe eines Argumentes beim Funktionsaufruf auf diese oder jene Art und Weise erfolgt. Der Eindruck, in Java würden Objekte by-reference übergeben, hat aber nichts mit der Übergabe an sich zu tun, sondern mit der Tatsache, dass Objekte in Java überhaupt nicht direkt angesprochen werden können, sondern stets nur über eine Referenz.
Diese Referenz verhält sich in allen Belangen wie ein primitiver Typ: Man kann sie z.B. zuweisen, man kann funktionslokal oder sonstwo Variablen dieses Typs deklarieren und insbesondere kann man sie by-value übergeben. Das Objekt liegt im Hintergrund und wird nur indirekt durch die Referenz angesprochen.Ehrlich gesagt, ist mir noch NIE Deine Standpunkt vorher untergekommen ... und es ist mit gut 600 Entwicklern doch ein recht großes Softwarehaus, in dem ich arbeite.
Haben die mal die Java Language Specification gelesen? Da wird beim Methodenaufruf nicht unterschieden zwischen Objekt- und primitiven Typen. Da steht einfach, dass die Argumentwerte übergeben werden.
-
Zum Glück wird es C immer geben

gruß mdoemli
-
Hi Bashar,
@"Ahnung haben":
ich sehe da keinen großen Widerspruch.
Es ist lediglich die Frage, wer die Bedeutung eines Begriffs festlegt: Einige Spezialisten, die ihn "korrekt verwenden" .... oder die 99% anderen, die sich zwar im Widerspruch zu den Experten befinden, sich untereinander aber im Wesentlichen einig sind. Ich spreche dabei nicht allgemein von "Wahrheitsfindung", sondern von "menschlicher Sprache" ... ein identisches Beispiel ist z.B. der Begriff "Quantensprung": Vergleiche da mal, was Physiker meinen und was alle anderen darunter verstehen.Und letztlich: Welchen Wert hat für den Programmierer die Kennzeichnung als "call-by-value", wenn sich für ihn alles so verhält wie ein "call-by-ref" ?
@"Referenzen wie primitive Typen":
Letztlich bleibt aber die "Zweiteilung" in primitive Typen (inklusive Referenzen) und "Klassentypen", oder ?
Und die werden nicht identisch gehandhabt, oder ?Gruß,
Simon2.
-
Simon2 schrieb:
@"Ahnung haben":
ich sehe da keinen großen Widerspruch.
Es ist lediglich die Frage, wer die Bedeutung eines Begriffs festlegt: Einige Spezialisten, die ihn "korrekt verwenden" .... oder die 99% anderen, die sich zwar im Widerspruch zu den Experten befinden, sich untereinander aber im Wesentlichen einig sind.Die Experten natürlich, zumindest dann, wenn es zum Streit über die Bedeutung kommt.
Allerdings kann ich auch Ignoranz nicht ausstehen, vielleicht ist meine Meinung da etwas vorgefärbt.
Ich spreche dabei nicht allgemein von "Wahrheitsfindung", sondern von "menschlicher Sprache" ... ein identisches Beispiel ist z.B. der Begriff "Quantensprung": Vergleiche da mal, was Physiker meinen und was alle anderen darunter verstehen.
call-by-reference ist aber nun nicht gerade ein Begriff, der in die Alltagssprache eingegangen ist und von Nichtfachleuten in vollkommen anderer Bedeutung verwendet wird.
@"Referenzen wie primitive Typen":
Letztlich bleibt aber die "Zweiteilung" in primitive Typen (inklusive Referenzen) und "Klassentypen", oder ?
Und die werden nicht identisch gehandhabt, oder ?Du kannst keine Variable deklarieren oder einen Ausdruck formulieren, der als Typ diesen Klassentyp hat. Da muss man doch glatt fragen, was genau soll denn ein Klassentyp sein? Und, wenn es sowas gibt, warum fragst du, ob die genauso wie primitive Typen gehandhabt werden?
-
Bashar schrieb:
...
call-by-reference ist aber nun nicht gerade ein Begriff, der in die Alltagssprache eingegangen ist und von Nichtfachleuten in vollkommen anderer Bedeutung verwendet wird....Naja, von den Leuten, mit denen ich gesprochen habe (und die Deiner Meinung nach ja keine Ahnung haben => "Nichtfachleute" sind), hat jedenfalls keiner Fragen zu dem Begriff gehabt.
Bashar schrieb:
...Da muss man doch glatt fragen, was genau soll denn ein Klassentyp sein? ...
Na der Typ dessen, was ich z.B.
- mit
class Irgendwas { ... }definiere, - mit
new Irgendwas;erzeuge, - über den Zugriff über die zugehörige Referenz bearbeite,
- auf irgendwohin casten darf oder eben nicht,
- mit einem instanceof abfragen kann,
- ...
Bashar schrieb:
...warum fragst du, ob die genauso wie primitive Typen gehandhabt werden?
... weil ich es wissen möchte.
Gruß,
Simon2.
- mit
-
Bashar schrieb:
Ich spreche dabei nicht allgemein von "Wahrheitsfindung", sondern von "menschlicher Sprache" ... ein identisches Beispiel ist z.B. der Begriff "Quantensprung": Vergleiche da mal, was Physiker meinen und was alle anderen darunter verstehen.
call-by-reference ist aber nun nicht gerade ein Begriff, der in die Alltagssprache eingegangen ist und von Nichtfachleuten in vollkommen anderer Bedeutung verwendet wird.
Programmierer vs Compilerbauer?
-
hallo zusammen,
hab mir jetzt nicht die ganze diskussion über call-by-xyz durchgelesen. also wenn meine antwort an der frage vorbei geht entschuldige ich mich im voraus.
als call-by-value bedeutet nur das ich einer funktion einen wert übergebe und falls er in dieser funktion geändert wird, ist die änderung nach rückkehr aus der funktion nicht sichtbar.
call-by-reference ist die änderung eben schon sichtbar. hier macht es meiner meinung keinen unterschied ob objekt oder primitiver datentyp. reference ist immer ein zeiger (ja gut für manche gibt es wesentliche unterschiede, für mich nicht).
der unterschied ist nur das ein objekt immer by-reference übergeben wird und bei einem primitiven datentyp muss man halt & angeben.hoffe das war irgendwie gefragt, wenn nicht sorry!!!
gruß, mdoemli
-
Simon2 schrieb:
Und letztlich: Welchen Wert hat für den Programmierer die Kennzeichnung als "call-by-value", wenn sich für ihn alles so verhält wie ein "call-by-ref" ?
Aber das Verhalten ist ja eben nicht call-by-ref in Java. Ansonsten müsste das hier funktionieren:
public void swap( Object a, Object b ){ Object t = a; a = b; b = t; } public void main(){ // jaja, bin zu faul hier alles sauber auszuschreiben Object x = "Eins"; Object y = "Zwei"; swap( x, y ); // gibt "Eins Zwei" aus, und nicht "Zwei Eins", wie das bei // call-by-ref sein müsste. // In C++ könnte man swap so schreiben, dass es einen Effekt hätte System.out.println( x + " " + y ); }Nur kommt in Java garniemand auf die Idee, solchen Code wie oben zu schreiben, "call-by-value" ist so sehr ins Fleisch gegangen, dass man sich keine Gedanken mehr darüber macht.
-
ahhh, java!!!
ok da ist es klar, da ja die reference eines objectes mit call-by-value übergeben wird.
-
JBeni schrieb:
...
public void swap( Object a, Object b ){ Object t = a; a = b; b = t; } public void main(){ // jaja, bin zu faul hier alles sauber auszuschreiben Object x = "Eins"; Object y = "Zwei"; swap( x, y ); // gibt "Eins Zwei" aus, und nicht "Zwei Eins", wie das bei // call-by-ref sein müsste. // In C++ könnte man swap so schreiben, dass es einen Effekt hätte System.out.println( x + " " + y ); }Du spielst hier auf eine besondere Perfidität von Java an, nämlich, dass ein "operator=()" auf die Referenz selbst ausgeführt wird.
Anders herum: Wäre es call-by-value, warum funktioniert dann Folgendespublic void change( Object a){ a.set("Zwei"); } public void main(){ Object x = "Eins"; change( x ); // gibt "Zwei" aus, und nicht "Eins", wie das bei // call-by-value sein müsste. // In C++ könnte man swap so schreiben, dass es einen Effekt hätte System.out.println( x ); }Aber offensichtlich reden wir hier über 2 verschiedene Dinge: call-by-XY und "call-with-copy".
Mir ging es eigentlich um Zweiteres (dass das implizit bei primitiven Typen erzwungen wird) und für mich war das dasselbe wie "call-by-value" ... ist es aber vermutlich nicht.Gruß,
Simon2.
-
JBeni! So einen ähnlichen Test haben wir in unserer Java-Projekttruppe auch mal gemacht. Man, hab ich ins Klo gegriffen!
Seit dem mache ich mir in Java darüber keine Gedanken. Wenn ich ein Objekt entgegen nehme, kann ich dessen Methoden aufrufen - fertig. Alles andere was ich aus C++ kenne, verbanne ich aus meinem Kopf, wenn ich Java mache. Denn die Kollegen von mir, die noch nie C++ gemacht haben, haben mich bei der Wette geschlagen. 
-
Simon2! Eben, du kannst das Objekt bzw. dessen Attribute durch setter ändern, aber mehr auch nicht.
-
ok, ganz einfach.
fall 1:
a und b sind kopien der referenz, d.h.
a zeigt auf x und
b zeigt auf y.
so da die a und b kopien sind und dadurch call by value, verlierst du die referenzen nach beendigung der funktion.in deinem fall schreibst du direkt auf ein objekt, trotzdem verlierst du die referenzen a und b.
x y
value value (value = attribut vom object)so a und zeigt nun auf die selbe speicherzelle wie x. nun kannst du über a auf das
attribut value schreiben, aber du verlierst dann denn zeiger a (aber deswegen bleibt doch das objekt erhalten).hoffe das ist irgendwie klar geworden.
also zeiger auf objekt immer call-by-value
gruß, mdoemli
-
Bashar schrieb:
Call-by-xyz heißt, dass die Übergabe eines Argumentes beim Funktionsaufruf auf diese oder jene Art und Weise erfolgt.
Was genau der Sichtweise entspricht, dass Du die Referenz übergibst. Schaust Du aber so drauf, dass Du das referenzierte Objekt übergibst, dann ist es call by reference.