Was macht das Q_OBJECT-Makro? Warum benötigen alle Qt-Objekte dieses Makro?
131
Ich habe gerade mit Qt angefangen und festgestellt, dass alle Beispielklassendefinitionen das Makro Q_OBJECTals erste Zeile haben. Was ist der Zweck dieses Präprozessor-Makros?
Der Meta-Object Compiler, moc, ist das Programm, das die C ++ - Erweiterungen von Qt verarbeitet.
Das moc-Tool liest eine C ++ - Headerdatei. Wenn eine oder mehrere Klassendeklarationen gefunden werden, die das Q_OBJECT-Makro enthalten, wird eine C ++ - Quelldatei erstellt, die den Metaobjektcode für diese Klassen enthält. Unter anderem wird Metaobjektcode für den Signal- und Slot-Mechanismus, die Laufzeittypinformationen und das dynamische Eigenschaftssystem benötigt.
warum muss ich nicht explizit schreiben Q_OBJECT::connect(), sondern nur connect()?
mLstudent33
19
Es teilt dem Pre-Compiler einfach mit, dass diese Klasse GUI-Elemente enthält und über das 'moc' ausgeführt werden muss. Sie müssen dies nur Klassen hinzufügen, die den Signal- / Slot-Mechanismus verwenden.
In anderen Klassen wird es jedoch stillschweigend ignoriert - es verlängert nur die Erstellungszeit.
Es ist auch falsch, dass Sie es nur für Klassen benötigen, die den Signal- / Slot-Mechanismus verwenden. Das Fehlen von Q_OBJECTBrüchen qobject_castund Selbstbeobachtung. Es kann zu verwirrendem Verhalten führen, daher ist es eine schlechte Idee.
Stellen Sie Monica am
2
Es ist nicht wahr, dass Q_OBJECTin anderen (Nicht- QObject) Klassen "leise" ignoriert wird . Gemäß dem C ++ - Standard wird undefiniertes Verhalten eingeführt, indem mehrere Elementfunktionen und Variablen deklariert werden, die niemals definiert werden. Außerdem wird der Namespace Ihrer Klasse mit bestimmten QObjectMitgliedern verschmutzt . Q_OBJECTZum Beispiel kann a eine nicht verwandte Klasse brechen, die zufällig eine aufgerufene Methode enthält metaObject.
Stellen Sie Monica am
2
Das ist falsch. Obwohl Sie wahrscheinlich die meisten GUI-Klassen mit dem Q_OBJECTMakro ausstatten möchten , ist es durchaus sinnvoll, Nicht-GUI-Klassen mit dem Makro sowie GUI-Klassen ohne das Makro zu haben. Das Makro ist nützlich, aber für GUI-Klassen weder beschränkt noch erforderlich.
Pasbi
9
Der MOC (Meta Object Compiler) konvertiert die im Q_OBJECT-Makro enthaltenen Header-Dateien in C ++ -äquivalenten Quellcode. Es steuert im Wesentlichen den Signal-Slot-Mechanismus und macht ihn für den C ++ - Compiler verständlich
Das ist falsch: Das Q_OBJECTMakro wird vom Compiler erweitert, dafür wird moc nicht benötigt. Das moc macht nichts mit dem Makro selbst, sondern generiert die Definitionen der Mitgliedsvariablen und -methoden, die das Q_OBJECTMakro deklariert hat .
Das moc-Tool liest eine C ++ - Quelldatei. Wenn eine oder mehrere Klassendeklarationen gefunden werden, die das Makro Q_OBJECT enthalten, wird eine weitere C ++ - Quelldatei erstellt, die den Metaobjektcode für jede dieser Klassen enthält. Diese generierte Quelldatei wird entweder # in die Quelldatei der Klasse aufgenommen oder in der Regel kompiliert und mit der Implementierung der Klasse verknüpft.
Das Q_OBJECT-Makro muss im privaten Abschnitt einer Klassendefinition erscheinen, die ihre eigenen Signale und Slots deklariert oder andere Dienste verwendet, die vom Metaobjektsystem von Qt bereitgestellt werden.
Das moc-Tool liest eine C ++ - Headerdatei. Wenn eine oder mehrere Klassendeklarationen gefunden werden, die das Q_OBJECT-Makro enthalten, wird eine C ++ - Quelldatei erstellt, die den Metaobjektcode für diese Klassen enthält. Unter anderem wird Metaobjektcode für den Signal- und Slot-Mechanismus, die Laufzeittypinformationen und das dynamische Eigenschaftssystem benötigt.
Das Q_OBJECT-Makro wird vom Präprozessor erweitert, um mehrere Mitgliedsfunktionen zu deklarieren, die vom moc implementiert werden. Wenn Sie Compilerfehler im Sinne von "undefinierter Verweis auf vtable für LcdNumber" erhalten, haben Sie wahrscheinlich vergessen, den moc auszuführen oder die moc-Ausgabe in den Link-Befehl aufzunehmen.
In gcc mit sehen -ESie erweiterte Makros. Dies ist, was Q_OBJECTauf gcc unter Linux erweitert wird. Beachten Sie, dass dies möglicherweise plattformabhängig ist und sich je nach Version von QT ändern kann. Sie sehen, es ist nicht nur ein Tag für den moc-Compiler.
Das Q_OBJECT-Makro muss im privaten Abschnitt einer Klassendefinition erscheinen, die ihre eigenen Signale und Slots deklariert oder andere Dienste verwendet, die vom Metaobjektsystem von Qt bereitgestellt werden.
Dies ist irreführend: Das Q_OBJECTMakro muss in jeder Klasse erscheinen, von der abgeleitet wird QObject. Ihr Code wird auf subtile Weise beschädigt, wenn das Makro fehlt, und nur weil es gerade kompiliert wird, ist es nicht in Ordnung.
Stellen Sie Monica am
@KubaOber Haben Sie ein Beispiel für Code, der kompiliert wird, aber nicht funktioniert, wenn das Q_OBJECTMakro fehlt?
Chris
2
Wenn Sie sich die Implementierung von ansehen Q_OBJECT, werden Sie feststellen, dass Zugriffsspezifizierer verwendet werden. Es ist also unerheblich, ob das Makro unter dem private, protectedoder unter den publicBezeichnern angezeigt werden soll - es ist nur eine Konvention, es an die Spitze der Klasse zu setzen.
Antworten:
Aus der Qt-Dokumentation :
quelle
Q_OBJECT::connect()
, sondern nurconnect()
?Es teilt dem Pre-Compiler einfach mit, dass diese Klasse GUI-Elemente enthält und über das 'moc' ausgeführt werden muss. Sie müssen dies nur Klassen hinzufügen, die den Signal- / Slot-Mechanismus verwenden.
In anderen Klassen wird es jedoch stillschweigend ignoriert - es verlängert nur die Erstellungszeit.
quelle
Q_OBJECT
Brüchenqobject_cast
und Selbstbeobachtung. Es kann zu verwirrendem Verhalten führen, daher ist es eine schlechte Idee.Q_OBJECT
in anderen (Nicht-QObject
) Klassen "leise" ignoriert wird . Gemäß dem C ++ - Standard wird undefiniertes Verhalten eingeführt, indem mehrere Elementfunktionen und Variablen deklariert werden, die niemals definiert werden. Außerdem wird der Namespace Ihrer Klasse mit bestimmtenQObject
Mitgliedern verschmutzt .Q_OBJECT
Zum Beispiel kann a eine nicht verwandte Klasse brechen, die zufällig eine aufgerufene Methode enthältmetaObject
.Q_OBJECT
Makro ausstatten möchten , ist es durchaus sinnvoll, Nicht-GUI-Klassen mit dem Makro sowie GUI-Klassen ohne das Makro zu haben. Das Makro ist nützlich, aber für GUI-Klassen weder beschränkt noch erforderlich.Der MOC (Meta Object Compiler) konvertiert die im Q_OBJECT-Makro enthaltenen Header-Dateien in C ++ -äquivalenten Quellcode. Es steuert im Wesentlichen den Signal-Slot-Mechanismus und macht ihn für den C ++ - Compiler verständlich
quelle
Q_OBJECT
Makro wird vom Compiler erweitert, dafür wird moc nicht benötigt. Das moc macht nichts mit dem Makro selbst, sondern generiert die Definitionen der Mitgliedsvariablen und -methoden, die dasQ_OBJECT
Makro deklariert hat .1 Aus der Qt-Dokumentation des Meta-Object-Systems
Das moc-Tool liest eine C ++ - Quelldatei. Wenn eine oder mehrere Klassendeklarationen gefunden werden, die das Makro Q_OBJECT enthalten, wird eine weitere C ++ - Quelldatei erstellt, die den Metaobjektcode für jede dieser Klassen enthält. Diese generierte Quelldatei wird entweder # in die Quelldatei der Klasse aufgenommen oder in der Regel kompiliert und mit der Implementierung der Klasse verknüpft.
2 Aus der Qt-Dokumentation von THE Q_OBJECT
Das Q_OBJECT-Makro muss im privaten Abschnitt einer Klassendefinition erscheinen, die ihre eigenen Signale und Slots deklariert oder andere Dienste verwendet, die vom Metaobjektsystem von Qt bereitgestellt werden.
3 Aus der Qt-Dokumentation von moc
Das moc-Tool liest eine C ++ - Headerdatei. Wenn eine oder mehrere Klassendeklarationen gefunden werden, die das Q_OBJECT-Makro enthalten, wird eine C ++ - Quelldatei erstellt, die den Metaobjektcode für diese Klassen enthält. Unter anderem wird Metaobjektcode für den Signal- und Slot-Mechanismus, die Laufzeittypinformationen und das dynamische Eigenschaftssystem benötigt.
4 Aus der Qt-Dokumentation von Signalen und Slots
Das Q_OBJECT-Makro wird vom Präprozessor erweitert, um mehrere Mitgliedsfunktionen zu deklarieren, die vom moc implementiert werden. Wenn Sie Compilerfehler im Sinne von "undefinierter Verweis auf vtable für LcdNumber" erhalten, haben Sie wahrscheinlich vergessen, den moc auszuführen oder die moc-Ausgabe in den Link-Befehl aufzunehmen.
quelle
In gcc mit sehen
-E
Sie erweiterte Makros. Dies ist, wasQ_OBJECT
auf gcc unter Linux erweitert wird. Beachten Sie, dass dies möglicherweise plattformabhängig ist und sich je nach Version von QT ändern kann. Sie sehen, es ist nicht nur ein Tag für den moc-Compiler.quelle
Das Q_OBJECT-Makro muss im privaten Abschnitt einer Klassendefinition erscheinen, die ihre eigenen Signale und Slots deklariert oder andere Dienste verwendet, die vom Metaobjektsystem von Qt bereitgestellt werden.
quelle
Q_OBJECT
Makro muss in jeder Klasse erscheinen, von der abgeleitet wirdQObject
. Ihr Code wird auf subtile Weise beschädigt, wenn das Makro fehlt, und nur weil es gerade kompiliert wird, ist es nicht in Ordnung.Q_OBJECT
Makro fehlt?Q_OBJECT
, werden Sie feststellen, dass Zugriffsspezifizierer verwendet werden. Es ist also unerheblich, ob das Makro unter demprivate
,protected
oder unter denpublic
Bezeichnern angezeigt werden soll - es ist nur eine Konvention, es an die Spitze der Klasse zu setzen.