Que fait la macro Q_OBJECT? Pourquoi tous les objets Qt ont-ils besoin de cette macro?
131
Je viens de commencer à utiliser Qt et j'ai remarqué que toutes les définitions de classe d'exemple ont la macro Q_OBJECTcomme première ligne. Quel est le but de cette macro de préprocesseur?
Le compilateur de méta-objets, moc, est le programme qui gère les extensions C ++ de Qt.
L'outil moc lit un fichier d'en-tête C ++. S'il trouve une ou plusieurs déclarations de classe contenant la macro Q_OBJECT, il produit un fichier source C ++ contenant le code de méta-objet pour ces classes. Entre autres choses, le code de méta-objet est nécessaire pour le mécanisme des signaux et des slots, les informations de type d'exécution et le système de propriétés dynamiques.
pourquoi n'ai-je pas besoin d'écrire explicitement Q_OBJECT::connect()mais plutôt juste connect()?
mLstudent33
19
Il indique simplement au pré-compilateur que cette classe a des éléments d'interface graphique et doit être exécutée via le «moc», il suffit de l'ajouter aux classes qui utilisent le mécanisme signal / slot.
Mais il sera discrètement ignoré dans toutes les autres classes - cela ne fait qu'ajouter au temps de construction.
Il est également faux que vous n'en ayez besoin que sur les classes qui utilisent le mécanisme signal / slot. L'absence de Q_OBJECTrupture qobject_castet d'introspection. Cela peut conduire à un comportement déroutant, c'est donc une mauvaise idée.
Réintégrer Monica le
2
Ce n'est pas vrai que ce Q_OBJECTsera "discrètement" ignoré dans les autres (non- QObject) classes. Selon le standard C ++, il introduit un comportement indéfini en déclarant plusieurs fonctions membres et variables qui ne sont jamais définies. Il pollue également l'espace de noms de votre classe avec des QObjectmembres spécifiques. Par exemple, un Q_OBJECTpeut bien casser une classe non liée qui contient une méthode appelée metaObject.
Réintégrer Monica le
2
C'est faux. Bien que vous souhaitiez probablement équiper la plupart des classes gui avec la Q_OBJECTmacro, il est parfaitement logique d'avoir des classes non-gui avec la macro, ainsi que des classes gui sans la macro. La macro est utile, mais ni limitée ni requise pour les classes d'interface graphique.
pasbi
9
Le MOC (compilateur de méta-objets) convertit les fichiers d'en-tête inclus de la macro Q_OBJECT en code source équivalent C ++. Il contrôle essentiellement le mécanisme de créneau de signal et le rend compréhensible pour le compilateur C ++
C'est faux: la Q_OBJECTmacro est développée par le compilateur, moc n'est pas nécessaire pour cela. Le moc ne fait rien avec la macro elle-même, mais il génère les définitions des variables membres et des méthodes que la Q_OBJECTmacro a déclarées .
Réintégrer Monica le
5
1 De la documentation Qt du système de méta-objets
L'outil moc lit un fichier source C ++. S'il trouve une ou plusieurs déclarations de classe contenant la macro Q_OBJECT, il produit un autre fichier source C ++ qui contient le code de méta-objet pour chacune de ces classes. Ce fichier source généré est soit # inclus dans le fichier source de la classe, soit, plus généralement, compilé et lié à l'implémentation de la classe.
La macro Q_OBJECT doit apparaître dans la section privée d'une définition de classe qui déclare ses propres signaux et slots ou qui utilise d'autres services fournis par le système de méta-objets de Qt.
L'outil moc lit un fichier d'en-tête C ++. S'il trouve une ou plusieurs déclarations de classe contenant la macro Q_OBJECT, il produit un fichier source C ++ contenant le code de méta-objet pour ces classes. Entre autres choses, le code de méta-objet est nécessaire pour le mécanisme des signaux et des slots, les informations de type d'exécution et le système de propriétés dynamiques.
La macro Q_OBJECT est développée par le préprocesseur pour déclarer plusieurs fonctions membres qui sont implémentées par le moc; si vous obtenez des erreurs de compilation du type "référence indéfinie à vtable pour LcdNumber", vous avez probablement oublié d'exécuter le moc ou d'inclure la sortie moc dans la commande link.
Dans gcc avec -Evous pouvez voir les macros développées. C'est ce qui se Q_OBJECTdéveloppe sur gcc sous Linux. Sachez que cela peut dépendre de la plate-forme et que cela peut changer en fonction de la version de QT. Vous pouvez voir que ce n'est pas seulement une balise pour le compilateur moc.
La macro Q_OBJECT doit apparaître dans la section privée d'une définition de classe qui déclare ses propres signaux et slots ou qui utilise d'autres services fournis par le système de méta-objets de Qt.
Ceci est trompeur: la Q_OBJECTmacro doit apparaître dans chaque classe qui dérive de QObject. Votre code sera subtilement cassé lorsque la macro est absente, et ce n'est pas parce qu'elle se compile que cela fonctionne.
Réintégrer Monica le
@KubaOber avez-vous un exemple de code qui se compile mais ne fonctionne pas lorsque la Q_OBJECTmacro est manquante?
Chris
2
Si vous regardez l'implémentation de Q_OBJECT, vous constaterez qu'elle utilise des spécificateurs d'accès. Donc , si la macro doit apparaître dans la sous private, protectedou publicspécificateurs est hors de propos - il est convention juste pour le placer à la tête de la classe.
Réponses:
De la documentation Qt :
la source
Q_OBJECT::connect()
mais plutôt justeconnect()
?Il indique simplement au pré-compilateur que cette classe a des éléments d'interface graphique et doit être exécutée via le «moc», il suffit de l'ajouter aux classes qui utilisent le mécanisme signal / slot.
Mais il sera discrètement ignoré dans toutes les autres classes - cela ne fait qu'ajouter au temps de construction.
la source
Q_OBJECT
ruptureqobject_cast
et d'introspection. Cela peut conduire à un comportement déroutant, c'est donc une mauvaise idée.Q_OBJECT
sera "discrètement" ignoré dans les autres (non-QObject
) classes. Selon le standard C ++, il introduit un comportement indéfini en déclarant plusieurs fonctions membres et variables qui ne sont jamais définies. Il pollue également l'espace de noms de votre classe avec desQObject
membres spécifiques. Par exemple, unQ_OBJECT
peut bien casser une classe non liée qui contient une méthode appeléemetaObject
.Q_OBJECT
macro, il est parfaitement logique d'avoir des classes non-gui avec la macro, ainsi que des classes gui sans la macro. La macro est utile, mais ni limitée ni requise pour les classes d'interface graphique.Le MOC (compilateur de méta-objets) convertit les fichiers d'en-tête inclus de la macro Q_OBJECT en code source équivalent C ++. Il contrôle essentiellement le mécanisme de créneau de signal et le rend compréhensible pour le compilateur C ++
la source
Q_OBJECT
macro est développée par le compilateur, moc n'est pas nécessaire pour cela. Le moc ne fait rien avec la macro elle-même, mais il génère les définitions des variables membres et des méthodes que laQ_OBJECT
macro a déclarées .1 De la documentation Qt du système de méta-objets
L'outil moc lit un fichier source C ++. S'il trouve une ou plusieurs déclarations de classe contenant la macro Q_OBJECT, il produit un autre fichier source C ++ qui contient le code de méta-objet pour chacune de ces classes. Ce fichier source généré est soit # inclus dans le fichier source de la classe, soit, plus généralement, compilé et lié à l'implémentation de la classe.
2 De la documentation Qt de THE Q_OBJECT
La macro Q_OBJECT doit apparaître dans la section privée d'une définition de classe qui déclare ses propres signaux et slots ou qui utilise d'autres services fournis par le système de méta-objets de Qt.
3 De la documentation Qt de moc
L'outil moc lit un fichier d'en-tête C ++. S'il trouve une ou plusieurs déclarations de classe contenant la macro Q_OBJECT, il produit un fichier source C ++ contenant le code de méta-objet pour ces classes. Entre autres choses, le code de méta-objet est nécessaire pour le mécanisme des signaux et des slots, les informations de type d'exécution et le système de propriétés dynamiques.
4 Depuis la documentation Qt des signaux et des slots
La macro Q_OBJECT est développée par le préprocesseur pour déclarer plusieurs fonctions membres qui sont implémentées par le moc; si vous obtenez des erreurs de compilation du type "référence indéfinie à vtable pour LcdNumber", vous avez probablement oublié d'exécuter le moc ou d'inclure la sortie moc dans la commande link.
la source
Dans gcc avec
-E
vous pouvez voir les macros développées. C'est ce qui seQ_OBJECT
développe sur gcc sous Linux. Sachez que cela peut dépendre de la plate-forme et que cela peut changer en fonction de la version de QT. Vous pouvez voir que ce n'est pas seulement une balise pour le compilateur moc.la source
La macro Q_OBJECT doit apparaître dans la section privée d'une définition de classe qui déclare ses propres signaux et slots ou qui utilise d'autres services fournis par le système de méta-objets de Qt.
la source
Q_OBJECT
macro doit apparaître dans chaque classe qui dérive deQObject
. Votre code sera subtilement cassé lorsque la macro est absente, et ce n'est pas parce qu'elle se compile que cela fonctionne.Q_OBJECT
macro est manquante?Q_OBJECT
, vous constaterez qu'elle utilise des spécificateurs d'accès. Donc , si la macro doit apparaître dans la sousprivate
,protected
oupublic
spécificateurs est hors de propos - il est convention juste pour le placer à la tête de la classe.