Am Samstag, dem 20. April 2002 um 11:24:29, schrieb Konrad Rosenbaum:
Da sagst du schon einen meiner Kritikpunkte: "kompliziert".
Mit kompliziert meinte ich nicht die Syntax, sondern die Datenstrukturen, die sich der Programmierer zur Lösung seines konkreten Problems überlegt hat. Das ist völlig unabhängig von der jeweiligen Programmiersprache. Ziel meines Wrappers ist es gerade, die Umsetzung möglichst einfach zu machen.
Was mache ich eigenlich, wenn sich die Assoziationen mittendrin veraendern. Z.B. ein Update-Button, an dem etwa zwei dutzend Elemente haengen, die sich dynamisch veraendern koennen (es kommen staendig einzelne Elemente dazu oder gehen weg, abhaengig von den Daten, die anfallen).
Hier hatte ich gestern Abend zu kurz nachgedacht. Die von mir verwendeten Callbacks sind richtige C++-Konstrukte mit Rückgabewerten (die im Einzelfall auch void sein KÖNNEN) im Gegensatz zu den QT-Slots. Damit ist dein Vergleich einer zwischen Äpfeln und Birnen. Oder wie willst du dein obiges Beispiel in plain Qt realisieren, wenn alle Elemente wichtige Daten zurückliefern?
Im übrigen ist ein weiterer Nachteil der Signal-Slot-Geschichte die Laufzeitperformance, weil es auf Zeichenkettenvergleichen beruht.
Dein gestriges Problem mit dem automatische Löschen der Callbacks lässt sich elegant lösen, wenn man nicht - wie ich in meinem Beispiel - mit Pointern, sondern entweder mit smart-Pointern oder direkten Kopien des Objekts arbeitet. Es ist also kein Problem, es sah in meinem Beispiel bloss so aus, als könnte es eins werden.
hmm, was fuer ein Ausdruck ist jetzt "bind<string, int>(lexical_cast, _1)"? Cast? Template?
Wegen <> sind bind und lexical_cast Templates. Was es mit _1 auf sich hat, muss ich nicht wissen, um es verwenden zu können.
Wenn Template, dann lies Dir mal bitte durch, warum Qt keine Templates verwendet (doc/html/templates.html).
Ja, die Begründung finde ich lustig: sie berufen sich darauf, dass sie auch alte Compiler unterstützen wollen. Als vor Jahren der Flamewar um QT in C++ versus plain C bei anderen Bibliotheken lief, war die Begründung, dass man für GUI unbedingt C++ bräuchte und weniger eben nicht ginge, basta! Jetzt, wo es gute Compiler gibt (selbst MS VC++ soll in der aktuellsten Version nicht so schlecht sein), benutzen sie es nicht.
Was, wenn ich einen neuen Typ einfuehre, den bind noch nicht kennt? Muss ich dann bind ueberschreiben?
Bind ist ein Template und kennt keine konkreten Typen. Du solltest dich unbedingt mal mit Templates in C++ beschäftigen, bevor du darüber schreibst!
connect(SIGNAL(abc(int,int,QString,float)),obj1,SLOT(int,int)))
- ->bei Qt vollkommen legaler und funktionierender Code.
Das ist kein legaler C++-Code, wenn die letzten beiden Argumente von abc keine Defaultwerte haben. Qt ist broken, wenn es das trotzdem tut. Wenn es aber Defaultwerte gibt, ist es legal und geht auch mit den von mir vorgestellten Konstrukten.
Wieso kommst Du auf sowas? Etwa ein Viertel der Qt-Klassen haben nichts, aber auch gar nichts, mit GUI zu tun, Beispiele:
Okay das ist ein anderes Thema, "Bollin" soll bloss ein GUI-Wrapper sein und nicht mehr als das leisten. Reiner Anwendungscode soll bei mir frei von bollin- bzw. Qt-Headern sein und das geht mit "Bollin".
Hmm, wieso ist das ein Vorteil. So viel Zeit verbraet der doch gar nicht (im Vergleich zum eigentlichen Compiler).
GCC 3.1 führt wohl für die ia64-Plattform ein standardisiertes C++-ABI ein. Sowas wie moc macht diese interessante Entwicklung wertlos.
Am Samstag, dem 20. April 2002 um 11:33:56, schrieb Konrad Rosenbaum:
Hmm, wer ist Alexandrescu? Noch nie gehoert.
Wurde kürzlich als bestes C++-Buch 2001 in comp.lang.iso-c++ gekürt.
Good C++ libraries sport this interesting feature...
Welches Feature?
Kapitel 5 ("Generalized Functors"), gemeint ist an der Stelle, dass es manchmal zu Uneindeutigkeiten kommt, die der Compiler nicht selbst auflösen kann und der Programmierer expliziten Code schreiben kann/muss. Wie z. B. oben:
bind<string, int>(lexical_cast, _1);
statt nur:
bind(lexical_cast, _1);
Aber das hat mit unserem Thema wenig zu tun.
- die starke Typisierung verhindert echte Polymorphie
... Der Signal-Slot-Mechanismus gibt mir einen grossen Teil der Polymorphie zurueck.
Das erscheint mir ohne Begründung als totaler Nonsens. Alexandrescu schreibt ein eigenes Kapitel über Multimethods (double dispatch) in C++. Mach das erst einmal in Java! Kennt Smalltalk so etwas? Im Buch werden CLOS, ML, Haskell und Dylan als Beispiele mit Sprachunterstützung für Multimethods aufgeführt.
- es besitzt keinen Garbage Collector (der hilft wirklich sehr, bei
komplexen Objekt-hierarchien/-netzen)
C++ hat hier eine andere Vorgehensweise, die einen Garbage Collector meines Erachtens unnötig machen. Der einzige echte Nachteil ist, dass das Anfängern etwas schwer fällt.
Im Übrigen ist deine Kritik wenig hilfreich. "Bollin" soll ein dünner und angenehm zu benutzender Wrapper für Qt sein. Wer gern auf die Qt-Mechanismen durchgreifen will, kann das tun. Die Bibliothek verbietet so etwas nicht bzw. macht das noch nicht einmal schwer.
Torsten