-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Saturday 20 April 2002 13:33, Torsten Werner wrote:
Am Samstag, dem 20. April 2002 um 11:24:29, schrieb Konrad Rosenbaum:
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?
a) Ein weiteres Signal in der Gegenrichtung werfen. b) Parameter als Referenzen uebergeben.
Aber eigentlich sollte das nicht noetig sein, weil Signal-Slot Ereignisse abbildet und die sind nur in eine Richtung definiert. Nach dem Prinzip der Kapselung sollte es den Signaller nicht interessieren, ob es eine Ereignisbehandlung gibt.
"Der Vulkan bricht halt aus, ob jemand wegrennt ist ihm egal." ;-)
Im übrigen ist ein weiterer Nachteil der Signal-Slot-Geschichte die Laufzeitperformance, weil es auf Zeichenkettenvergleichen beruht.
Lt. Qt-Docu etwa 10-facher Aufwand eines einfachen Funktionsaufrufes. Da Ereignisse relativ selten sind (verglichen mit Warteschleifen und mathematischem Code) kann ich damit leben.
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.
Smart Pointer klingt gut. Aber Kopien koennten ein Problem 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.
Templates haben noch einen weiteren Nachteil: jede Object-Datei erzeugt eine neue Instanz des Codes. Nur wenige Linker (der von GNU z.B. nicht) koennen soetwas wieder reduzieren.
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!
Ich weiss, was Templates sind. Es war eine Frage, kein Vorwurf. Ich war davon ausgegangen, dass es eine einfache Funktion ist.
connect(SIGNAL(abc(int,int,QString,float)),obj1,SLOT(int,int)))
Ups, das sollte SLOT(def(int,int)) heissen.
- ->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? Einem Signal gibst Du Parameter mit, die der Slot aufnehmen kann oder auch nicht. Wenn ein Slot nicht an Paramer 3 und 4 interessiert ist, dann brauch er den doch nicht abfangen muessen, nur weil irgendein dummes Signal den Parameter liefern koennte.
Beispiel: QLineEdit implementiert ein Signal textchanged(QString). QButton (und damit QCheckBox) implementiert toggled(bool). Angenommen ich baue eine Art Formular und will nur wissen, ob Daten veraendert wurden, dann brauche ich bei Qt nur diese beiden Signal mit einem SLOT(changed()) zu verbinden, wohin sich etwas geaendert hat ist mir sch***egal, ich will ja nur den Save-Button aktivieren.
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, ich finde im Anwendungs-/Daten-modell soetwas wie Signal-Slot eigentlich auch sehr nuetzlich. Bekomme ich in einem Chat-Client z.B. eine Anfrage von einem anderen Nutzer kann ich das sehr elegant mit Qt-Mechanismen durch meine Blacklist-Filter jagen, bevor ich irgendetwas an die GUI durchreiche.
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.
Was bitte hat ein Application Binary Interface mit einem Preprocessor zu tun?
Willst Du jetzt auch Embedded SQL verbieten?
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.
Aha, danke.
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.
Hmm. Muss ich mir bei Gelegenheit mal ansehen, im Moment verstehe ich diesen Code nicht. :-(
- 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.
1. Java ist ebenso eine stark typgebundene Sprache wie C++.
2. AFAIK wurde double dispatch von SmallTalk _erfunden_! Unter anderem, weil SmallTalk nur drei Sprachkonstrukte kennt: Objekte/Methoden, Methoden-Aufrufe und Variablen. Double Dispatch macht einige weitere Konstrukte (wie z.B. switch) ueberfluessig.
- 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.
Bitte jetzt keinen Flamewar ausbrechen lassen....
<Einschub> Fuer alle Anfaenger/Nicht-Programmier-Experten, die sich wundern, was hier los ist: es gibt zwei Philosophien unter Programmierern a) Speicherverwaltung ist zu schwierig/nervend, um sie dem Programmierer aufzuhalsen (Garbage Collector Befuerworter) b) Speicherverwaltung ist zu schwierig, um sie einem (dummen) Rechner zu ueberlassen (GC Gegner).
GC's haben Vorteile: * man braucht sich nicht selbst um die Freigabe von Speicher zu kuemmern * (theoretisch) kann ein Programm keine Speicherloecher mehr haben
und Nachteile: * sie tendieren dazu immer dann etwa 20s lange Saeuberungszyklen einzulegen, wenn man die Prozessorzeit fuer etwas anderes braucht * sie verbrauchen relativ viel Ressourcen (sowohl Speicher, als auch CPU-Zyklen) </Einschub>
Der einzige echte Nachteil ist, dass das Anfängern etwas schwer fällt.
Ich bin zwar kein Anfaenger mehr, aber bei den komplexen Modellen, die ich in den letzten Jahren angefangen habe aufzubauen faellt mir die Speicherverwaltung zu oft auf die Fuesse. Ich habe begonne GC's zu moegen.
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.
Hmm, ich dachte Du wolltest Kommentare?
Ich versuche nur potentielle Schwachstellen aufzuzeigen, sag' Bescheid, wenn ich aufhoeren soll, dann schreib ich lieber Code als eMails.
Konrad
- -- Suffocating together ... would create heroic camaraderie. -- Khan Noonian Singh, "Space Seed", stardate 3142.8