2 von 2 Kunden fanden die folgende Rezension hilfreich:
1.0 von 5 Sternen
Unbrauchbar, 12. November 2011
Rezension bezieht sich auf: Qt 4 - GUI-Entwicklung mit C++: Das umfassende Handbuch, m. CD-ROM (Gebundene Ausgabe)
Es ist interessant zu beobachten, mit welcher Frequenz Jürgen Wolf sogenannte Fachbücher auf den Markt wirft. Ein Allroundgenie sozusagen. Besonders bewundernswert ist dabei sein Selbstbewusstsein, dies ohne wirklicher Erfahrung und teilweise sogar ohne Kenntnis der besprochenen Thematik zu tun. Diesbezüglich steht sein Buch zur Programmierung mit Qt den bisher erschienenen Werken in nichts nach.
Dabei fängt es schon bei Begriffen der C bzw. C++-Grundlagen an. "Code schreiben" ist für ihn etwas anderes als "implementieren", wobei beide Ausdrücke in diesem Fall (Erklärung über beispiele/signalslot4/myclass.h) das selbe Beschreiben:
"Der Code für Signal-Elementfunktionen wird aber nicht vom Program-
mierer, sondern vom Meta Object Compiler (kurz MOC) geschrieben.
[...]
Wir erstellen eine einfache Klasse mit einem Integerwert als Eigenschaft und
implementieren in dieser Klasse das Signal valueChanged(int)"
Wobei hier "implementieren" wohl "deklarieren" hätte heißen sollen.
Im selben Stil verwendet er "Deklaration der Klasse" für die eigentliche Definition, Definition der Klasse ist für ihn allein die Implementierung der Methoden.
Die ganze Erklärung zum moc, warum er gebraucht wird, die Verbindung zum C++-Standard etc. ist nur noch zum Kopfschütteln.
Da im Prinzip jeder Satz Ungenauigkeiten bzw. Fehler enthält hier eine kleine Auswahl:
* "dass das Signal-Slot-Konzept kein reines C++ ist" - es ist ein Konzept und damit komplett unabhängig von C++. boost::signals(2) kommt ohne eigenem moc aus, der Code lässt sich alein mit Hilfe des Compilers übersetzen - ist das jetzt trotzdem kein C++?
* "Der Meta Object Compiler verwandelt daher Signale und Slots in echten C++-konformen Standard" - Wie kann etwas in einen Standard verwandelt werden?
* "Somit ist MOC also ein Programm, das einen C++-Quelltext einliest und die C++-Erweiterung von Qt verwaltet." - moc verwaltet gar nichts, moc liest Code ein und generiert daraus C++-Code, mehr nicht. Hierbei werden auch nicht wie postuliert automatisch immer Dateien angelegt und nach fixem Namensschema benannt - dies geschieht nur auf ausdrücklichen Befehl (cmdline-Args für moc).
* "Kurz gesagt, benötigt man MOC immer dann, wenn QObject als Basisklasse dient." - Falsch. Polymorphismus scheint dem Autor völlig unbekannt zu sein. QObject und davon abgeleitete Klassen besitzen virtuelle Methoden, die man implementieren kann. Q_OBJECT und moc sind völlig unnötig, wenn man das paintEvent oder keyboard/mouse-Handler eine Widgets anpassen will, oder ein reines EventFilter-Objekt braucht.
An anderer Stelle verwendet er Formulierungen wie "Sender empfängt ein Signal" oder "Sender erhält ein Signal". Genauer gesagt versendet der Sender ein Signal - oh Wunder.
Für ihn existiert nur die statische connect-Funktion, das überladene connect ignoriert er.
Er sagt, Standardparameter wären bei Signals und SLots verboten - stimmt nicht, es gibt sogar einen eigenen Punkt zu dem Thema (den gab es noch nicht bei der oft in seinen Screenshots auftauchenden Version 4.2, möglich war es aber da auch schon immer!)
Genauso sagt die Doku zum moc, dass Signals und Slots return types haben können. Wie der Autor zur Aussage "Allerdings dürfen die deklarierten Signal- und Slot-Elementefunktionen keinen Rückgabetyp haben und müssen daher void sein." kommt, ist von daher unerklärlich, weist er doch ausdrücklich darauf hin, dass sowohl SIGNALS als auch SLOTS ganz normale Funktionen sind. Die eigentliche Frage wäre, ob und wie man diese return types, speziell bei signals, nutzen kann.
Was er zu Beginn von 2.1.4 mit "Es kann keine eigene Ereignisklasse definiert werden, die nur aus Signalen und Slots besteht." meint, ist mir auch nicht klar. Natürlich kann eine Klasse vollkommen ohne sonstiger Member, Kosntruktoren, etc. auskommen. Einzig das "Q_OBJECT" muss drinnen stehen - an der Stelle kennt der Leser aber Q_OBJECT noch nicht, weshalb der Satz zu falschen Annahmen verleiten kann.
Kapitel 3 verwurschtelt gleich mal "Prozess" und "Thread".
Qt betreibt auch keine "automatische Speicherverwaltung" (3.2) sondern eher automatische Speicherbereinigung (im Sinne von Garbage Collection).
Seine Programmierempfehlung, auf die Header QtCore, QtGui etc. (in seiner Sprache "Meta-Include-Headerdateien") zu setzen anstatt auf die einzelnen Header "QPushButton" etc., läuft gegen jede von tatsächlichen Experten vertretene Meinung, nur das einzubinden was tatsächlich benötigt wird. Seine Erklärung: Heutzutage hat ja eh jeder vorkompilierte Header...
Dass man slots als private oder public deklarieren kann, protected aber nur in Verbindung mit virtual ist lachhaft. Genauso der Hinweis, signals als "private" zu deklarieren - das gibt einen netten Compilefehler - sollte man ausprobieren!
Das waren jetzt eher Kleinigkeiten, die mehr verwirren und den Leser irreleiten.
Ein klein wenig schlimmer wird es zu Beginn von 2.1.5 bei der Erklärung, warum diese Verbindung nicht funktioniert: Die Argumentliste stimmt nicht überein. Das ist eigentlich nicht das Problem. Beim connect werden Funktionssignaturen erwartet. Ein "SIGNAL(func(int value))" wird auch schief gehen, da die Signatur auf keine als signal registrierte Funktion passt - die wäre func(int). Ein "neuer Text" ist aber kein Typ sondern ein "Wert" (ein character-literal) - was erst in der Zusammenfassung so formuliert ist. Dass clicked() keine Argumenete an den SLOT weitergibt ist klar, das liegt aber nicht daran, dass die Argumentlisten nicht übereinstimmen, sondern schlicht daran, dass gar keine connection aufgebaut wurde!
Sein absolut nicht existentes Wissen über Qt und C++ demonstriert er uns aber in Kapitel 3.3.
Kurzum: "Klassenhierarchie != Objekthierarchie"!!!!!
Anhand einer durch Ableitung entstehenden Klassenhierarchie direkt auf das Löschen von Kind-Elementen in Objekthierarchien zu schließen ist schlichtweg - keine Ahnung ob es hierfür eine adäquate Bezeichnung gibt...
Seine Erklärung sagt uns: Wird ein QWidget gelöscht, werden auch alle QPushButtons gelöscht. Super... Wobei ihm im Folgetext immer öfter die Bezeichnung "Objekt" statt "klasse" reinrutscht (wobei natürlich Objekte von anderen Objekten erben können) - trotzdem werden die Aussagen nicht korrekter.
Auf diese Erklärung greift er dann später wieder zurück:
"Deswegen müssen die Kinderelemente eines Widgets immer GUI-Elemente eines übergeordneten Widgets sein."
Die Beispiele, die von Anfängern und Fortgeschrittenen normalerweise aufgesaugt werden und sich stilistisch für lange Zeit bei eigenen Programmen manifestieren, sind auch eher ein Witz.
Drei Beispiele:
* Die Implementierung von mainWidget::mousePressEvent() in Listings/paintEvent ist köstlich...
Codeduplizierung par excellence.
* Listings/qprinter2: preparePage() ruft am Ende direkt printPage() auf - es macht mehr als der Name verspricht!
* Listings/qprinter: Herr Wolf hat paintEvent() nicht verstanden. Dort wird Inhalt auf das Widget gemalt. Einen Dialog öffnet man dort nicht - niemals! Dass in paintEvent() ein weiterer QPainter auf das Widget aufgemacht wird (wenngleich indirekt über den QPrinter) geht gleich gar nicht! Herr Wolf sollte die Ausgaben seiner Programme etwas besser studieren:
"QWidget::repaint: Recursive repaint detected
QWidget::repaint: Recursive repaint detected"
Wer denkt, nach der Lektüre dieses Buches Qt programmieren zu können, ist auf dem Holzweg. Grundlagen werden schlichtweg falsch erklärt, Zusammenhänge verdreht. Auch die Beispiele sind durch die Bank nicht vorbildlich oder gar problematisch. Man sollte einen weiten Bogen um dieses Buch, am besten gleich um den Autor machen. Definitiv kann bzw. versteht er Qt nicht. Wie so ein Buch von fachkundigen Lektoren durchgewunken werden kann ist mir schleierhaft. Für dieses Buch Geld zu bezahlen erschließt sich mir nicht, vielmehr sollte dem Leser und allen Personen, die antrainierte Praktiken nach dem Studium solcher Bücher wieder ausbügeln dürfen, Schadensersatz gezahlt werden. Zum Glück gibt es auf der Seite des Autors eine Leseprobe sowie die Listings, sodass ich um den Erwerb dieses Buches herum gekommen bin. (Der aufmerksame Leser wird festgestellt haben, dass sich Kritikpunkte allein auf die Kapitel 2 und 3 beschränken. Ich habe hier auch nicht alles aufgeführt, da das den Rahmen der Rezension gesprengt hätte.)
Helfen Sie anderen Kunden bei der Suche nach den hilfreichsten Rezensionen
War diese Rezension für Sie hilfreich? Ja
Nein