c++ vs. java... was hat zukunft



  • finix: Ich verstehe Deinen Kommentar nicht. 😞



  • Jester schrieb:

    finix: Ich verstehe Deinen Kommentar nicht. 😞

    Naja, ist nur mein persönlicher Eindruck. Hier dieser "interfaces ... ganz im sinne von OOP eben", zuvor dieses Gewäsch von wegen kopieren in einer "OOP-Sprache"...



  • .filmor schrieb:

    pale dog schrieb:

    CStoll schrieb:

    Btw, und wie würdest du das von tntnet angegebene Beispiel (zum Thema const correctness) in Java umsetzen?

    in Java würde man interfaces herumreichen. damit kann man methoden gruppieren in z.b. nur-set, nur-get, oder was eben passt. interfaces erlauben eine schärfere trennung als 'const' oder 'nicht-const'

    Und wie schaut das in tntnets Beispiel aus? Bezieh' dich mal bitte direkt darauf.

    wie gesagt: interfaces. funktionen, die nichts verändern dürfen, kriegen eine referenz auf das 'nicht_veränderlich'-interface, dann können sie nur methoden aufrufen, die sie dürfen.
    Java hat kein 'const'. sie wollten's mal einbauen, haben's dann aber doch verworfen (die Java-community steht nicht so sehr auf 'feature creep', wie die anhänger der 'andere seite'. 'keep it simple' ist wichtiger). 😉

    .filmor schrieb:

    pale dog schrieb:

    ein anderer weg um (zur laufzeit) sicherzustellen, dass das originalobjekt nicht verändert wird: man erzeugt eine kopie (für den 'Point' ja recht einfach).

    Na herzlichen Glückwunsch. Und was ist mit einem Container?! Soll ich den auch kopieren? Das kann nicht dein Ernst sein.

    nee, natürlich nicht 😉
    nur wundert's mich schon etwas, dass die C++ fans hier ständig ihre copy-ctors und zuweisungsoperatoren in den himmel loben, aber wenn man mal was in Java kopieren will, dann heisst es gleich: 'das ist aber ein mist' 😞

    .filmor schrieb:

    Und zu Interfaces hat sich Konrad ja schon sehr passend geäussert.

    huch? stimmt ja. oha, das hab' ich übersehen. 😮

    .filmor schrieb:

    Es kann nicht sein, dass ich als Programmierer mehr Arbeit mache als der Compiler. Dann kann ich mir auch Assembler antun 😉

    naja, in Java muss man sowieso viel schreiben, das liegt aber meistens an den langen bezeichnern. ausserdem schreibt man 'ne klasse und dazugehörige interfaces nur einmal hin und dann hat man's. ich sehe da kein problem.
    🙂

    finix schrieb:

    Jester schrieb:

    finix: Ich verstehe Deinen Kommentar nicht. 😞

    Naja, ist nur mein persönlicher Eindruck. Hier dieser "interfaces ... ganz im sinne von OOP eben", zuvor dieses Gewäsch von wegen kopieren in einer "OOP-Sprache"...

    oh, tut mir leid 😞
    ich hacke meistens rein, was mir gerade so einfällt, nichts für ungut



  • pale dog schrieb:

    wie gesagt: interfaces. funktionen, die nichts verändern dürfen, kriegen eine referenz auf das 'nicht_veränderlich'-interface, dann können sie nur methoden aufrufen, die sie dürfen.
    Java hat kein 'const'. sie wollten's mal einbauen, haben's dann aber doch verworfen (die Java-community steht nicht so sehr auf 'feature creep', wie die anhänger der 'andere seite'. 'keep it simple' ist wichtiger). 😉

    Nein, MACHT und KONTROLLE sind wichtiger. BUAHAHAHAHA! 😃

    pale dog schrieb:

    .filmor schrieb:

    pale dog schrieb:

    ein anderer weg um (zur laufzeit) sicherzustellen, dass das originalobjekt nicht verändert wird: man erzeugt eine kopie (für den 'Point' ja recht einfach).

    Na herzlichen Glückwunsch. Und was ist mit einem Container?! Soll ich den auch kopieren? Das kann nicht dein Ernst sein.

    nee, natürlich nicht 😉
    nur wundert's mich schon etwas, dass die C++ fans hier ständig ihre copy-ctors und zuweisungsoperatoren in den himmel loben, aber wenn man mal was in Java kopieren will, dann heisst es gleich: 'das ist aber ein mist' 😞

    Das liegt daran, dass man hier nicht Kopieren sollte. Container sind groß und im Allgemeinen nicht trivial zu kopieren. Und genau deshalb sollte man das tunlichst unterlassen, wenn man nicht wirklich einen zweiten Datensatz benötigt (wofür mir so ad hoc keine Anwendung einfällt).

    pale dog schrieb:

    naja, in Java muss man sowieso viel schreiben, das liegt aber meistens an den langen bezeichnern. ausserdem schreibt man 'ne klasse und dazugehörige interfaces nur einmal hin und dann hat man's. ich sehe da kein problem.

    Das Problem liegt in der Wartbarkeit. Wenn du eine Methode zur Klasse hinzufügst musst du an mehreren, eigentlich unabhängigen Stellen im Code Änderungen durchführen. Und jetzt komm mir nicht mit dem "Argument", das seien CnP-Änderungen 😉



  • .filmor schrieb:

    Und jetzt komm mir nicht mit dem "Argument", das seien CnP-Änderungen 😉

    copy&paste 😕
    nö, rechte maustaste -> refactor -> move to interface (oder ähnlich).
    ...aber sowas kennt ihr C++ user ja nicht 😉



  • pale dog schrieb:

    Java hat kein 'const'. sie wollten's mal einbauen, haben's dann aber doch verworfen (die Java-community steht nicht so sehr auf 'feature creep', wie die anhänger der 'andere seite'. 'keep it simple' ist wichtiger). 😉

    Um wieviel simpler ist denn Java mittlerweile noch? 🙂 Aber ja, wenn ich mir das rumgeheule wegen Closures ansehe weiß ich was du meinst 😃



  • pale dog schrieb:

    .filmor schrieb:

    Und jetzt komm mir nicht mit dem "Argument", das seien CnP-Änderungen 😉

    copy&paste 😕
    nö, rechte maustaste -> refactor -> move to interface (oder ähnlich).
    ...aber sowas kennt ihr C++ user ja nicht 😉

    In der Tat. Ich lasse doch keine Skripte an meinem Code arbeiten, soweit kommts noch 😉



  • 50 Seiten. rofl



  • Zu dem Container-Problem, man könnte ja in den Containern die Mutable-Klasse einfügen lassen, aber alle Methoden, die die Elemente nicht verändern dürfen kriegen halt nur das Interface als Parameter.

    import devent.point.PointInterface;
    import devent.point.Point;
    import devent.point.MutablePoint;
    
    //...
    List<MutablePoint> liste = new LinkedList<MutablePoint>();
    
    public void darfNichtsVerändern(PointInterface point)
    {
        // point hat nur getter
    }
    
    public void darfVerändern(MutablePoint point)
    {
        // point hat getter und setter
    }
    
    //...
    for ( PointInterface point : liste )
    {
        darfNichtsVerändern(point);
        darfVerändern(point);
    }
    

    Man kann ja auch List<PointInterface> nehmen, aber dann müste man in darfVerändern(MutablePoint) explizit nach MutablePoint casten.

    Apropos C++ und das der Compiler einem Code abnimmt. Das war einer der Gründe wieso ich Java gegenüber C++ vorziehe: Die Header-Files. Wieso muss ich in den Headers private Felder angeben? Wozu soll das gut sein, den zugreifen kann ich doch sowieso nicht? Wozu überhaupt Header-Files? Ich bin dermaßen froh das man sowas nicht in Java/C# übernommen hat. Das man in Header-Files überhaupt Variablen deklarieren kann ist sowieso der Wahnsinn schlecht hin.



  • DEvent schrieb:

    Zu dem Container-Problem, man könnte ja in den Containern die Mutable-Klasse einfügen lassen, aber alle Methoden, die die Elemente nicht verändern dürfen kriegen halt nur das Interface als Parameter.

    Eh? Es geht doch nicht darum wie sich ein Anwender am besten an den Vertrag halten kann, sondern wie der Besitzer es Containers diesen a) kommunizieren und b) absichern kann.

    DEvent schrieb:

    Man kann ja auch List<PointInterface> nehmen, aber dann müste man in darfVerändern(MutablePoint) explizit nach MutablePoint casten.

    Hehe, noch mehr Boilerplate code für die 3-in-1 Klasse, und zwar überall wo sie (in Collections) verwendet wird? Klasse. Ist aber - s.o. - ohnehin keine Lösung.

    edit: Mit den Headern hast du natürlich recht, aber das ist wohl, wie so manches in C++, ganz einfach historisch bedingt.



  • pale dog schrieb:

    ...
    kannst du das etwas genauer beschreiben?
    was hätte ein C++ compiler gemerkt?
    ...und warum hattet ihr pech mit Java?

    Hi,

    "Pech" war, dass wir so viele Programmierfehler in der Anwendung hatten, dass das erste Release bei den Pilotkunden komplett durch- und das Folgerelease wegen absoluter Terminüberschreitung im Test ebenfalls ins Wasser fiel. Unsere Fusionspläne mit einer anderen Firma liegen seitdem (über 1 Jahr) auf Eis (nachdem schon ein unterschriftsreifer Vertrag vorlag), ein Vorstand und ein Bereichsleiter wurden gefeuert und die gesamte Firma umstrukturiert. (immerhin 1400 Mitarbeiter in der Firma)

    Grund war jeweils, dass nach der "Compilierbarkeit" die Testphase viel zu kurz eungeschätzt wurde (und für Korrekturen/Redesign kaum Zeit eingeplant wurden) ... falsch geschätzt auf Basis von "Harten Sprachen" (bei denen der Compiler sehr viel genauer hinschaut).

    Ich will und kann ich nicht belegen, dass das mit C++ nicht passiert wäre, aber es waren doch erstaunlich viele Fehler dabei, die man mit "Ownership" und const hätte vermeiden können - ganz zu schweigen von den (in java doch eher üblichen) Nullpointerexceptions bei fachlichen Fehlern ... mit denen leider weder die Automaten noch die menschlichen User etwas anfangen konnten.
    Außerdem hätten keine schnellen Compiliererfolge Termintreue vorgegaukelt .... 😃

    Das wird nicht nur (und vielleicht nicht mal hauptsächlich - wer könnte das schon nachweisen ?) an der Sprache gelegen haben, sondern auch an Vielem Anderen - trotzdem bin ich der Meinung, dass mit C++ diese anderen Schwächen eher aufgefallen wären, gerade weil es nicht den Eindruck erweckt, jeder Anfänger könne aus dem Stand korrekten Code schreiben.

    Außerdem wollte ich nur mal ein Beispiel dafür anführen, dass man auch mit Java (und auch im "BusinessApp-Umfeld") auf die Nase fliegen kann. Unser C++-Projekt (wenn auch deutlich kleiner, trotzdem mit knapp 2Mio€ nicht gerade winzig) dagegen war ein Musterbeispiel für C++:

    • Lief von Anfang an fehlerfrei (wenn auch noch nicht optimal stabil)
    • War simpel skalierbar bei steigender Last
    • Ist bis heute "Musterbeispiel" für unseren Kunden und
    • dauerte und kostete 150% der urspränglichen Schätzung 😉 (kam aber deutlich früher heraus als bei obigem Javaprojekt)

    😉

    Gruß,

    Simon2.

    P.S.: Ich weiß nicht, ob C++ uns wirklich besser geholfen hätte...



  • pale dog schrieb:

    .filmor schrieb:

    pale dog schrieb:

    ein anderer weg um (zur laufzeit) sicherzustellen, dass das originalobjekt nicht verändert wird: man erzeugt eine kopie (für den 'Point' ja recht einfach).

    Na herzlichen Glückwunsch. Und was ist mit einem Container?! Soll ich den auch kopieren? Das kann nicht dein Ernst sein.

    nee, natürlich nicht 😉
    nur wundert's mich schon etwas, dass die C++ fans hier ständig ihre copy-ctors und zuweisungsoperatoren in den himmel loben, aber wenn man mal was in Java kopieren will, dann heisst es gleich: 'das ist aber ein mist' 😞

    Wir wollen ja nicht alles kopieren - und bei einem vector oder ähnlichem wissen wir, daß er zu groß dafür ist und übergeben ihn als const-Referenz. Übrigens kamen die Argumente ala "Kopieren ist Mist" auch und vorwiegend von der Java-Seite 😉

    .filmor schrieb:

    Und zu Interfaces hat sich Konrad ja schon sehr passend geäussert.

    huch? stimmt ja. oha, das hab' ich übersehen. 😮

    .filmor schrieb:

    Es kann nicht sein, dass ich als Programmierer mehr Arbeit mache als der Compiler. Dann kann ich mir auch Assembler antun 😉

    naja, in Java muss man sowieso viel schreiben, das liegt aber meistens an den langen bezeichnern. ausserdem schreibt man 'ne klasse und dazugehörige interfaces nur einmal hin und dann hat man's. ich sehe da kein problem.
    🙂

    Lange Bezeichner sind kein Problem, Redundanzen in meinen Augen schon (ja, ich weiß, mit dem Header-Konzept baue ich mir auch Redundanzen im C++ Quelltext ein - aber dort informiert mich der Compiler, wenn ich eine Methodendeklaration vergessen habe).

    (und woher weiß dein refactore-Script, welche Methoden nun in das Point-Interface gepackt werden sollen?)

    DEvent schrieb:

    Zu dem Container-Problem, man könnte ja in den Containern die Mutable-Klasse einfügen lassen, aber alle Methoden, die die Elemente nicht verändern dürfen kriegen halt nur das Interface als Parameter.

    Ja, solange ich nur einzelne Punkte durchreichen will, ist das womöglich eine Lösung. Aber kann ich meine List<MutablePoint> an eine Funktion übergeben, die eine List<PointInterface> erwartet?

    PS: Wie ich gestern schon geschrieben habe, sehe ich einen (semantischen) Unterschied zwischen ausgewachsener Klasse (im Sinne der Objektorientierung) und Hilfsklasse (als einfache Möglichkeit, Werte sinnvoll zu gruppieren) mit jeweils unterschiedlicher Zuweisungssemantik. Bei einer ausgewachsenen Klasse ist das Referenzverhalten durchaus sinnvoll, bei einer Hilfsklasse ist Kopiersemantik angebrachter.
    C++ lässt mich klar entscheiden, was ich bauen möchte, Java setzt die Trennlinie imho zu weit unten an (ja, ich kann einer Klasse einen Copy-Ctor und eine Clone()-Methode spendieren - aber ich kann niemanden dazu zwingen, diese Methoden zu verwenden, wenn er Objekte zuweist (oder etwa doch?)).



  • CStoll schrieb:

    (und woher weiß dein refactore-Script, welche Methoden nun in das Point-Interface gepackt werden sollen?)

    das ist von der IDE abhängig, z.b. einfach die methoden auswählen, dann 'extract interface' oder sowas anklicken, dann den namen eines neuen interfaces eingeben oder den eines bestehenden auswählen und fertig.

    CStoll schrieb:

    (ja, ich kann einer Klasse einen Copy-Ctor und eine Clone()-Methode spendieren - aber ich kann niemanden dazu zwingen, diese Methoden zu verwenden, wenn er Objekte zuweist (oder etwa doch?)).

    z.b. könnte man alle anderen konstruktoren 'protected' machen und den copy-construktor 'public', dann kann ausserhalb des packages nur der copy-constructor aufgerufen werden.

    CStoll schrieb:

    Bei einer ausgewachsenen Klasse ist das Referenzverhalten durchaus sinnvoll, bei einer Hilfsklasse ist Kopiersemantik angebrachter.

    ich finde nicht, dass man es daran festmachen sollte.
    kopieren würde ich nur, wenn es sinnvoll ist oder sich nicht vermeiden lässt, sonst nicht.
    🙂



  • pale dog schrieb:

    CStoll schrieb:

    (ja, ich kann einer Klasse einen Copy-Ctor und eine Clone()-Methode spendieren - aber ich kann niemanden dazu zwingen, diese Methoden zu verwenden, wenn er Objekte zuweist (oder etwa doch?)).

    z.b. könnte man alle anderen konstruktoren 'protected' machen und den copy-construktor 'public', dann kann ausserhalb des packages nur der copy-constructor aufgerufen werden.

    Und kann ich auf diese Weise auch die (in Java normale) Referenz-Zuweisung ala 'MyHelper x = y;' verbieten lassen?

    CStoll schrieb:

    Bei einer ausgewachsenen Klasse ist das Referenzverhalten durchaus sinnvoll, bei einer Hilfsklasse ist Kopiersemantik angebrachter.

    ich finde nicht, dass man es daran festmachen sollte.
    kopieren würde ich nur, wenn es sinnvoll ist oder sich nicht vermeiden lässt, sonst nicht.
    🙂

    Hilfsklassen sind solche, wo Kopieren sinnvoll (und mitunter notwendig) ist. Und solche kann ich in Java nicht ohne Komplikationen compilieren.

    Mal zur Anschauung ein Beispiel - ich baue mir ein Strategie-Spiel mit der Klassenhierarchie:

    class Koord//Hilfsklasse, um die Position einer Einheit zu beschreiben
    {
    private:
      int x,y;
    public:
      ...
      void Move(int dx,int dy)
      { x+=dx;y+=dy; }
    };
    
    class GameObject
    {
    private:
      Koord pos;//wo befinde ich mich?
    public:
      ...
    };
    
    class Soldier : public GameObject
    {...};
    
    class Fabric : public GameObject
    {
    private:
      Koord spos;//Startposition für erzeugte Soldaten
    public:
      Soldier* create_soldier(...)
      {
        Soldier* s = new Soldier(spos);//neue Soldaten stehen an der Startposition für die Fabrik
        return s;
      }
      ...
    };
    

    In C++ hat jeder Soldat und jede Fabrik seine eigene Position und spos wird kopiert, wenn es benötigt wird. In Java sind pos und spos nur Referenzen. Das heißt ich als Programmierer muß daran denken, eine Kopie der Position anzulegen um dann den erzeugten Soldaten damit zu initialisieren.
    (ich denke womöglich noch daran, weil das ja mein Design ist. Aber womöglich erweitert ein Kollege das Spiel um eine bewegliche Fabrik und ob der daran denkt, ist die andere Frage)



  • CStoll schrieb:

    Referenz-Zuweisung ala 'MyHelper x = y;' verbieten lassen?

    Das kannste doch in C++ auch nicht verbieten, dass einer sich nen Pointer auf ein Objekt kopiert.

    Btw, da spos ja schon zu GameObject gehört mußte es nur ein einziges mal richtig machen, nämlich im Konstruktor von GameObject. Fehler machen kann man natürlich viele. Und Du gibst Dir da scheinbar auch besondere Mühe. 🙂



  • Ja, aber ich kann verhindern, daß jemand den Pointer bekommt 😉 (zur Not, indem ich operator& entschärfe :D)



  • CStoll schrieb:

    Ja, aber ich kann verhindern, daß jemand den Pointer bekommt 😉 (zur Not, indem ich operator& entschärfe :D)

    Meinst Du das ernst?



  • Nicht wirklich (beachte das :D). Aber in meinem objigen Beispiel sind die Koord-Werte private Member. Das heißt ohne meine Erlaubnis kommt niemand an diese Objekte heran.

    (und nebenbei benötige ich die Koord-Angaben sicher noch für mehr Angaben als nur die aktuelle Position einer Einheit (dazu hätten auch zwei int-Member in der GameObject-Klasse gereicht) - einige davon in Klassen, die vom ursprünglichen Design überhaupt noch nicht vorgesehen waren)



  • Jester schrieb:

    CStoll schrieb:

    Referenz-Zuweisung ala 'MyHelper x = y;' verbieten lassen?

    Das kannste doch in C++ auch nicht verbieten, dass einer sich nen Pointer auf ein Objekt kopiert.

    und das ist eine ganz üble sache!
    (jetzt muss ich leider auch mal mit C++ vergleichen) 😉
    den pointer kann man sich in C++ lustig zurechtcasten wie man will und hebelt damit sämtliche schutzmechanismen wie 'const' und 'protected' aus.
    in Java kann man inkompatible typen oder objektreferenzen, die nicht verwand sind, nicht 'zwangscasten'.
    na, welche sprache bietet besseren schutz? 😃



  • Schutz gegen Vorsatz (und Sachen wie reinterpret_cast<> sind Vorsatz) kann wohl keine Sprache geben - Schutz gegen Fahrlässigkeit schon (dazu gehört z.B. die Möglichkeit, jemandem rein lesenden Zugriff auf meine Daten zu geben).

    PS: Und afair sind alle Klassen in Java miteinander verwandt - und wenn nur über ihren Urahnen Object.


Anmelden zum Antworten