Windowsprogramm mit C++ oder Java?



  • Zeus schrieb:

    Nun ja, wieso willst du den uberladen.

    Normalerweise willst du doch nur die Operatorenüberladen, die deine Klassen intuitiv Benutztbar machen, allerdings nur paar Operatoren überladbar zumachen ist wiederrum nicht sehr inkonsequent.

    Ist eigentlich dann C# als Sprache konsequenter als C++? 😃



  • In Bezug auf was? :o



  • Zeus schrieb:

    In Bezug auf was? :o

    Dacht es wäre klar...
    In C# kannst du nicht einzelne Operatoren überladen, z.B. musst du, wenn du den operator== überlädst, auch den operator!= überladen.



  • Hi DEvent,

    sorry, hat ein wenig gedauert - aber jetzt: 😃

    DEvent schrieb:

    ...

    ich will keinen Krieg vom Zaun brechen, aber Dir trotzdem sanft widersprechen (im Sinne eines hilfreichen Gedankenaustauschs)

    Krieg ist wohl ein wenig übertrieben 😃 ...

    Nicht, wenn man den Verlauf einiger "Diskussion" zu ähnlichen Themen hier ansieht. 😉

    DEvent schrieb:

    ...Bei Java hat man aber den Unterschied eh immer....

    Eben - finde ich einfach nicht gut und auch inkonsistent. 😃
    Schränkt letztlich gerade bei der "Templateschreibung" ein.
    (Würde mir wünschen, dass man in C++ auch von ints ableiten könnte)

    DEvent schrieb:

    ...Gibts dafür ein Beispiel? Man kann in Java ein Sortieralgo Container- und Datentypunabhängig schreiben. ...

    Echt ? Habe ich noch nicht gesehen - bin aber auch nicht die Oberkoryphäe in Sachen Java. Ich habe immer nur Containermethoden zum Suchen oder Sortieren gesehen.

    DEvent schrieb:

    ...In OO-Sprachen kannst du gerne prozedural Programmieren.

    class Fooo
    {
        public Fooo(parameter)
        { schritt_1(); }
        public void schritt_1()
        { schritt_2(); }
        public void schritt_2()
        { schritt_3(); }
    }
    

    ...

    Äh, das ist auch nicht das Beispiel für eine "Prozedur", denn hier geht es offensichtlich um eine "Statusmaschine", die von Aufrufer bedient wird (einen Sortieralgo würdest Du doch auch nicht so umsetzen, oder ?). Wenn schon, dann wäre das passende Beispiel (hast Du unten schon ählich selbst genannt):

    class Fooo
    {
        public Fooo(parameter)    { 
          schritt_1();
          schritt_2();
          schritt_3();
          schritt_4();
          schritt_5();
          schritt_6();
       }
    }
    

    Und da sehe ich zum Einen nix "OO-iges", außer dass man eine "class ..." um seine Funktionssammlung geschrieben hat und zum Anderen ist es IMO ein typisches Beispiel für "unnötiger Userverwirrung": Bei einem Objekt muss ich davon ausgehen, dass es später noch existiert und dass es einen "Lebenszyklus" mit Status hat.... damit stellt sich z.B. beim Such-Objekt die Frage, was der Unterschied ist, ob ich erst Objekt A oder erst Objekt B suche.

    DEvent schrieb:

    ...

    class Funktion
    {
        public Function(parameter)
        { this.parameter = parameter; }
    
        public value fooo()
        { return mach_was_mit_den_paramtern(); }
    }
    
    // ...
        xxx = new Function(parameter).fooo();
    

    Hmmm schön klingendes Beispiel - jetzt variiere ich es mal ein wenig:

    class MAC
    {
        public MAC(parameter)
        { this.parameter = parameter; }
    
        public value fooo()
        { return parameter; }
    }
    
    // ...
       MAC myMAC = new Function(parameter);
    
       myMAC.fooo();
    

    Vollkommen gültig und sieht auch erstmal sinnvoll aus ... und trotzdem irgendwie sinnfrei.
    Mit einer "freien Funktion" wäre das nicht passiert.

    WENN man ein "Gedächtnis"/"Status" (von Dir "Umgebungsvariablen" genannt), hat man es gar nicht mit einem der Problemstellungen zu tun, von denen ich rede ! Und da ist ein Objekt sicher eine gute Sache. Ich rede wirklich von "Algorithmen": Also ein Tier, das nach einmal auf ein Ding losgelassen wird und danach mit allem abgeschlossen hat.
    Ich will nicht sagen, dass ALLE Probleme so sind (und OO deswegen überflüssig wäre), sondern nur, dass es eben auch solche gibt - und das für die ein OO-Ansatz IMO schlechteres Design ist als ein prozeduraler.

    DEvent schrieb:

    ...
    Btw, wenn ich den Operator== überlade, wie kann ich dann noch auf Gleichheit und Identität prüfen?

    Fooo x, y;
    x = new Fooo(300);
    y = new Fooo(300);
    // x ist zwar gleich mit y, aber nicht identisch
    if ( x == y ) ...
    

    Ganz einfach: Mit dem operator==() !
    Fooo ist offensichtlich eine "Pointerklasse" und wenn der operator==() überladen ist, dann drückt sie aus, dass 2 Fooos genau dann identisch sind, wenn der operator==() das so sieht. Du hast jetzt keine Implementation dabeigepackt, aber vermutlich schwebte Dir so etwas wie ein Attribut-Vergleich vor.
    Diese Identität ist z.B. bei reinen Value-Typen sinnvoll. Du unterscheidest auch nicht zwischen 2 verschiedenen "3en", sondern 3 ist eben 3.
    Oder ein anderes Beispiel: Wenn man so eine Art "Singletons" baut: Es soll zu jedem Initialisierungswert nur ein Objekt geben - new wird noch geeignet überladen, dass es in der Tabelle bereits instantiierter Objekte nachsieht und nur die Adresse des bvereits bestehenden zurückgibt.

    Das Überladen eines operators ist einfach eine Designentscheidung, mit der man seiner Klasse bestimmte Eigenschaften mitgibt - und da sind eigene operatoren mächtige Mittel, die ich nicht missen möchte...

    Gruß,

    Simon2.



  • WENN man ein "Gedächtnis"/"Status" (von Dir "Umgebungsvariablen" genannt), hat man es gar nicht mit einem der Problemstellungen zu tun, von denen ich rede ! Und da ist ein Objekt sicher eine gute Sache. Ich rede wirklich von "Algorithmen": Also ein Tier, das nach einmal auf ein Ding losgelassen wird und danach mit allem abgeschlossen hat.
    Ich will nicht sagen, dass ALLE Probleme so sind (und OO deswegen überflüssig wäre), sondern nur, dass es eben auch solche gibt - und das für die ein OO-Ansatz IMO schlechteres Design ist als ein prozeduraler.

    class Tier
    {
        public Tier(initalisationsParameter) { }
    
        public void run() 
        { Algorithmus wird gestartet 
          wenn Algorithmus zuende, informiere alle Oberserver
        }
    
        public void addObserver(Observer o);
    }
    
    //...
    Tier tier = new Tier(anfangsparameter);
    tier.addObserver(this);
    tier.run();
    
    //...
    tier.run();
    
    //...
    tier.run();
    

    Was spricht gegen sowas? Solange die Anfangsparameter germerkt werden, kann man den Algorithmus "Tier" immer wieder laufen lassen und wenn er ferdig ist, wird ein Observer benachrichtigt, und ist danach "mit allem abgeschlosen". Wenn man andere Anfangsparameter haben will, erstellt man sich ein neues "Tier", oder man baut sich eine setAnfangsparameter() ein.

    Vollkommen gültig und sieht auch erstmal sinnvoll aus ... und trotzdem irgendwie sinnfrei.
    Mit einer "freien Funktion" wäre das nicht passiert.

    Ach echt?

    fooo meineFunktion(parameter) { return parameter; }
    
    //..
    meineFunktion(xxxxx);
    

    Versteh irgendwie nicht warauf du hinaus willst?

    Das Überladen eines operators ist einfach eine Designentscheidung, mit der man seiner Klasse bestimmte Eigenschaften mitgibt - und da sind eigene operatoren mächtige Mittel, die ich nicht missen möchte...

    Inzwischen sehe ich das eigentlich genauso...



  • DEvent schrieb:

    ...
    Was spricht gegen sowas? ...

    Nichts - nur, dass ich offenbar noch nicht klar gemacht habe, worauf ich eigentlich hinaus will, denn Du bringst immer wieder Beispiele an, wo ein Objekt die beste Designwahl ist und ich das auch so machen würde.
    "run" ist einfach gut als Eigenschaft/Fähigkeit einer Klasse zu modellieren und das Benachrichtigen von Observern auch.

    Mir geht es aber darum, dass es eben auch Dinge gibt, bei denen das NICHT so einfach geht. Nehmen wir z.B. das Verschlüsseln eines Textes: Wessen Eigenschaft ist das ? Des Schlüssels ? Des Textes ? ...
    Das geht IMO an eindeutigsten mit einer freien Funktion.

    DEvent schrieb:

    ...

    Vollkommen gültig und sieht auch erstmal sinnvoll aus ... und trotzdem irgendwie sinnfrei.
    Mit einer "freien Funktion" wäre das nicht passiert.

    Ach echt?

    fooo meineFunktion(parameter) { return parameter; }
    
    //..
    meineFunktion(xxxxx);
    

    Versteh irgendwie nicht warauf du hinaus willst?
    ...

    Tut mir leid, ich glaube, ich muss das wirklich besser ausdrücken.
    Für mich besteht der Unterschied zwischen

    Fooo myFooo;
    myFooo.meineFunktion(parameter) { return parameter; }
    

    und

    meineFunktion(parameter);
    

    darin, dass mir bei der zweiten Variante bewusst ist, dass ich höchstens den Zustand von "parameter" verändert habe (und dementsprechend ein identischer Aufruf exakt denselben Effekt hat).
    Oder mal von der Programmiererintention gesprochen: "Ich tue etwas mit parameter".

    Bei der ersten Variante "tue ich etwas mit myFooo" (evtl. auch mit parameter). Der innere Zustand von myFooo spielt in das Ergebnis mit rein und ich kann NICHT davon ausgehen, dass ein identischer Aufruf auch den identischen Effekt hat - selbst bei einer const-Funktion nicht, weil dazwischen ja nonconst-Methoden von myFooo aufgerufen worden sein könnten, die den inneren Zustand verändern.

    Zwar kann man das mit static-Funktionen abbilden, aber IMO ist das nur eine Imitation von freien Funktionen in namespaces....

    Sagen wir mal so: Die Existenz von static-Funktionen in Java zeigt mir, dass freie Funktionen eigentlich doch sinnvoll sein können. 😃

    Ich hoffe, es wurde etwas klarer, was ich meinte....

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Sagen wir mal so: Die Existenz von static-Funktionen in Java zeigt mir, dass freie Funktionen eigentlich doch sinnvoll sein können.

    warum?
    mit 'static' funktionen kann man doch das selbe erreichen wie mit freien funktionen, nur passen sie besser zum konzept einer OO sprache wie z.b. Java.
    freie funktionen sind nur dann sinnvoll, wenn es keine static-funktionen gibt (und umgekehrt).
    ich finde es ist eine gute eigenschaft von Java, dass auf überflüssige und doppelt gemoppelte elemente verzichtet wird. das sorgt u.a. dafür, dass die sprache klar strukturiert und leicht verständlich bleibt...
    🙂



  • pale dog schrieb:

    Simon2 schrieb:

    Sagen wir mal so: Die Existenz von static-Funktionen in Java zeigt mir, dass freie Funktionen eigentlich doch sinnvoll sein können.

    warum?
    ...

    Hups ! Wie habe ich Dich denn in diesen Thread gelockt ? 😉

    @Topic: Ganz einfach: static functions sind einfach nicht mehr "OO". Sie beziehen sich nicht mehr auf ein Objekt, sondern führen lediglich mit "extern angelieferten Daten" Operationen aus ... genauso wie freie Funktionen.
    Hier bricht Java selbst mit seiner "Alles ist ein Objekt"-Maxime. Das ist auch in Ordnung, denn es ging mir um nicht mehr, als zu zeigen, dass es offensichtlich auch sinnvoll sein kann, aus diese Maxime auszuscheren.

    (Ich persönlich finde es aus o.g. Gründen konsistenter und eindeutiger, in dem Fall freie Funktionen zu verwenden, aber das spielt hier keine so große Rolle)

    Gruß,

    Simon2.



  • Saying Java is good because it works on all OSs is like saying anal sex is good because it works on all genders!



  • Bei der ersten Variante "tue ich etwas mit myFooo" (evtl. auch mit parameter). Der innere Zustand von myFooo spielt in das Ergebnis mit rein und ich kann NICHT davon ausgehen, dass ein identischer Aufruf auch den identischen Effekt hat - selbst bei einer const-Funktion nicht, weil dazwischen ja nonconst-Methoden von myFooo aufgerufen worden sein könnten, die den inneren Zustand verändern.

    Ich weis jetzt worauf du hinaus willst, und prinzipiel hast du Recht. Wenn man eine Methode blaaa.fooo(parameter) aufruft, dann macht die Methode etwas am Objekt blaaa und die Parameter sind eher nebensächlich.

    Man könnte dann höchstens eine finale Klasse schreiben, die nur const-Methoden hat...



  • DEvent schrieb:

    ...
    Man könnte dann höchstens eine finale Klasse schreiben, die nur const-Methoden hat...

    Genau ... oder man macht es "the C++ way" mit freien Funktionen in einem namespace ... dann brauche ich mir nichtmal die Klasse durchzusehen, ob tatsächlich alle Funktionen const sind und ich den Sinn der Klasse richitg verstanden habe. 😃

    Gruß,

    Simon2.


Anmelden zum Antworten