Das ist das Ende von C++!



  • Ganz einfach. Eigentlich steht es da und ich kann es nur mit anderen Worten wiederholen. Du stellst Vermutungen auf, was an D inkonsequent wäre, hast es dir aber selber noch nicht wirklich gut angesehen. Das das keine gute Idee ist, sieht man am anderen Beispiel. Die Macher von D haben sich sicherlich genauso wie du Gedanken gemacht, aber sind sicherlich auch noch weiter gegangen und haben konkrete Ansätze ausprobiert.

    Zu D selber sage ich nichts, weil ich es mir ebenfalls nicht ausführlich genug dafür angesehen habe. Ich wollte dich also lediglich ermutigen, das selbe zu tun, bevor komische Vergleiche zu Java gezogen werden, über das dann auch noch inkorrekte Aussagen getroffen werden.



  • Mal ganz abseit: was für ne Parameterübergabe gibt's denn bitte in Java, wenn nicht per Referenz? Oder bezog sich das nur auf eingebaute Typen?



  • Optimizer schrieb:

    ...Zu D selber sage ich nichts, weil ich es mir ebenfalls nicht ausführlich genug dafür angesehen habe. Ich wollte dich also lediglich ermutigen, das selbe zu tun, bevor komische Vergleiche zu Java gezogen werden, über das dann auch noch inkorrekte Aussagen getroffen werden.

    Ach so - ich hatte die ganze Zeit gedacht, dass Du mir inhaltlich widersrechen würdest.

    Gruß,

    Simon2.

    P.S.: java-Strings halte ich (aus den besagten Gründen) immer noch für "zwittrig", aber das soll Dich nicht weiter stören. 😉



  • Jester schrieb:

    Mal ganz abseit: was für ne Parameterübergabe gibt's denn bitte in Java, wenn nicht per Referenz? Oder bezog sich das nur auf eingebaute Typen?

    Welche Aussage meinst Du (die sich auf eingebaute Typen beziehen könnte oder eben nicht) ?

    Gruß,

    Simon2.



  • Jester schrieb:

    Mal ganz abseit: was für ne Parameterübergabe gibt's denn bitte in Java, wenn nicht per Referenz? Oder bezog sich das nur auf eingebaute Typen?

    Naja es ist doch in Java immer by value. Wenn du einen Zeiger übergibst, wird der Zeiger kopiert. In jedem Fall wird es dir nie gelingen, einen Parameter für den Aufrufer zu manipulieren (also den Zeiger zu verbiegen). Du kannst auch noch so viel kopieren, nur mal angenommen wenn Java auch noch das referenzierte Objekt kopieren würde, könnte dieses wieder andere Objekte referenzieren und die würden wieder nicht kopiert. Man muss sich also schon auf die unterste Ebene stellen und mal klar sehen, dass ein *Zeiger* übergeben wird und dieser wird kopiert.

    Das ist das gleiche Verhalten wie in C++, deshalb hat es mich auch stark verwundert, wieso man da einen Unterschied diesbzgl. zu C++ sehen kann. Ich habe ja auch geschrieben, dass man es vielleicht kritisieren könnte, dass man in Java Objekte nie ohne Zeiger anfassen kann. Aber das Verhalten ist doch durchgehend, Parameter by value zu übergeben und einen C++ler sollte sowas wirklich nicht verwirren.



  • Optimizer schrieb:

    Jester schrieb:

    Mal ganz abseit: was für ne Parameterübergabe gibt's denn bitte in Java, wenn nicht per Referenz? Oder bezog sich das nur auf eingebaute Typen?

    Naja es ist doch in Java immer by value. Wenn du einen Zeiger übergibst, wird der Zeiger kopiert. In jedem Fall wird es dir nie gelingen, einen Parameter für den Aufrufer zu manipulieren (also den Zeiger zu verbiegen).

    Das ist dann wohl eine Frage der sichtweise. Letztlich wird natürlich immer irgendeine Adresse by value übergeben. Ich möchte meinen Funktionen üblicherweise bestimmte Objekte übergeben und sehe es dann so, dass das ein Aufruf by reference ist. Schließlich kann man Änderungen, die in der Funktion am Objekt stattfinden auch außen sehen. Ich finde aber auch, dass einen Pointer in C++ zu übergeben ein Call by reference ist.



  • Optimizer schrieb:

    Das ist das gleiche Verhalten wie in C++, deshalb hat es mich auch stark verwundert, wieso man da einen Unterschied diesbzgl. zu C++ sehen kann. Ich habe ja auch geschrieben, dass man es vielleicht kritisieren könnte, dass man in Java Objekte nie ohne Zeiger anfassen kann. Aber das Verhalten ist doch durchgehend, Parameter by value zu übergeben und einen C++ler sollte sowas wirklich nicht verwirren.

    Der Unterschied ist, daß du in C++ selber entscheiden kannst, ob du das Objekt oder nur einen Zeiger darauf übergeben kannst. In Java ist (fast) alles ein Zeiger - das heißt du kannst zwar nicht die Variable des Aufrufers umbeigen, aber du kannst auf jeden Fall ihren Inhalt manipulieren.

    (und das Verhalten ist nicht durchgehend - primitive Typen werden als Wert, alle anderen über einen Zeiger weitergereicht)



  • CStoll schrieb:

    (und das Verhalten ist nicht durchgehend - primitive Typen werden als Wert, alle anderen über einen Zeiger weitergereicht)

    Auf welche Sprache bezieht sich das? o.O



  • Zeus schrieb:

    CStoll schrieb:

    (und das Verhalten ist nicht durchgehend - primitive Typen werden als Wert, alle anderen über einen Zeiger weitergereicht)

    Auf welche Sprache bezieht sich das? o.O

    Java (zumindest so, wie ich es kennengelernt habe) - in C(++) kannst du schließlich detailliert festlegen, ob ein Objekt als Wert ( func(T x); ) oder als "Referenz" ( func(T& x); bzw. im erweiterten Sprachgebrauch func(T* x); übergeben wird, und das unabhängig ob T ein build-in oder ein selbstdefinierter Typ ist.



  • Hi,

    ich denke, die Verwirrung liegt einfach darin, dass hier bisweilen schleichend die Perspektive gewechselt wird:

    Ein oft genanntes Schlagwort (gerade in der Abgrenzung zu C/C++) bzgl. Java ist doch "Es gibt keine Zeiger !". Das steht in krassem Widerspruch dazu, dass tatsächlich in Java fast ausschließlich mit Zeigern gearbeitet wird - weiß eigentlich auch jeder, aber in den Sprachgebrauch ist das noch nicht so recht eingegangen: Es wird immer gesagt "Man bekommt/nimmt/übergibt ein Objekt" ... und das bezeichnet (im Fall von "übergeben") gerade den Fall "call-by-value". Das Übergeben einer Referenz (auch, wenn der Inhalt der Referenzvariable dazu kopiert wird) nennt man klassisch "call-by-reference" .... was sonst sollte man call-by-ref" nennen ?

    Niemand käme wohl auf die Idee in C++

    void f(MyType*);
    void f(MyType&);
    

    als "call-by-value" zu bezeichnen - obwohl doch auch hier die Referenzvariable kopiert wird ...

    Der eigentliche Knackpunkt ist eigentlich, dass man gar nicht die Wahl hat, ob man ein Objekt oder eine Referenz in die Finger bekommt: Man bekommt entweder immer eine Referenz (Klassentypen) oder immer ein Objekt (primitive Typen).
    Wer bei Klassentypen "call-by-value" implementieren will, muß von Hand kopieren (entweder vor dem Call oder in der Funktion) ...

    Gruß,

    Simon2.



  • Jo genau, C++ ist durchgehend ValueType-Orientiert während es in Java/C#/D beides gibt - naja.

    void f(MyType&);
    

    nennt man aber in c++ als Call-by-reference 😃

    class A{
    member1;
    member2;
    };
    
    A a1, a2;
    a1 = a2; // Alle Members von a2 wird auf a1 kopiert (Standardverhalten)
    
    func(A a) 
    {
     ...
    }
    
    func(b); // b wird durch call-by-value übergeben.
    

    Hmm Call-by-Value ohne was zu Hand zu machen, oder hassu von Java gesprochen? 😮



  • 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.

    Dadurch, dass man einen Zeiger übergibt bezieht sich die ganze Semantik dann auf den Zeiger und nicht mehr auf das Objekt. In Java muss halt einem klar sein, dass man grundsätzlich nur Objektzeiger in der Hand hat. Aber ich seh jetzt schon ein, dass es vielleicht nicht wirklich klar und endgültig definiert ist.



  • 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


Anmelden zum Antworten