En ce qui concerne les signaux et les emplacements, la macro Q_OBJECT
ajoute une déclaration de fonction virtuelle qt_metacall()
dans la déclaration de classe qui doit être définie ultérieurement par le moc
. (Il ajoute également quelques déclarations de conversion, mais ce n'est pas trop important.)
Le moc
lit le fichier d'en-tête et quand il voit la macro, il génère un autre fichier .cpp
nommé moc_headerfilename.cpp
avec les définitions aux fonctions virtuelles et - vous vous êtes peut-être demandé pourquoi vous pouviez vous en passer en mentionnant le signals:
dans votre fichier d'en-tête sans une définition correcte des signaux. Ainsi, lorsqu'un signal est appelé, la définition du fichier moc est exécutée et QMetaObject::activate()
est appelée avec le nom du signal et les arguments du signal. La fonction activate()
détermine ensuite les connexions établies et récupère les noms des emplacements appropriés.
Ensuite, il appelle qt_metacall
avec les noms de sous et les arguments donnés au signal et les délégués de la fonction metacall avec l'aide d'une grande switch
- déclaration case
aux emplacements réels.
Comme il n'y a pas de véritable informations d'exécution possible en C++ en ce qui concerne les noms réels pour les signaux et les machines à sous, comme cela a déjà été remarqué, ceux-ci seront codées par les SIGNAL
et SLOT
macros à de simples const char*
s (avec « 1 » ou "2" ajouté au nom pour distinguer les signaux des slots).
Comme est défini dans qobjectdefs.h
:
#define SLOT(a) "1"#a
#define SIGNAL(a) "2"#a
-
L'autre chose que le fait macro Q_OBJECT
est la définition des tr()
fonctions à l'intérieur de votre objet qui peut être utilisé pour traduire votre application.
Modifier Comme vous avez demandé ce que fait le qt_metacast
. Il vérifie si un objet appartient à certaine classe et s'il le renvoie le pointeur. Si elle ne le fait pas, il retourne 0.
Widget* w = new Widget();
Q_ASSERT(w->qt_metacast("Widget") != 0);
Q_ASSERT(w->qt_metacast("QWidget") != 0);
Q_ASSERT(w->qt_metacast("QObject") != 0);
Q_ASSERT(w->qt_metacast("UnrelatedClass") == 0);
Ceci est nécessaire pour fournir une réflexion d'exécution qui n'est pas possible autrement. La fonction est appelée dans QObject::inherits(const char *)
par exemple et vérifie simplement l'héritage.
dup: http://stackoverflow.com/questions/1406940/how-signal-and-slots-are-implemented-under-the-hood – elcuco