Symbole externe non résolu " public: structure virtuelle qmetaobject const * Thiscall Parent

J'ai hérité d'une classe de QObject:

class Parent: public QObject
{
    Q_OBJECT
    QObject* cl;

public:
    Parent(QObject *parent=0):QObject(parent) {
        cl = NULL;
    }

    QObject* getCl() const {
        return cl;
    }
    void setCl(QObject *obj) {
        cl = obj;
    }
};

, Mais quand j'écris :

Parent ev;

Je reçois l'erreur suivante:

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Parent::metaObject(void)const " (?metaObject@Parent@@UBEPBUQMetaObject@@XZ)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __thiscall Parent::qt_metacast(char const *)" (?qt_metacast@Parent@@UAEPAXPBD@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __thiscall Parent::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Parent@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
54
demandé sur VicVu 2013-01-05 14:11:25

21 réponses

Vous devez supprimer le dossier debug de votre application et l'exécuter à nouveau pour corriger ce problème.

64
répondu sayyed mohsen zahraee 2016-08-31 03:26:42

Si vous utilisez Visual Studio, supprimez la ligne Q_OBJECT du fichier d'en-tête, enregistrez le fichier, remettez Q_OBJECT dans le fichier d'en-tête, enregistrez à nouveau le fichier. Cela devrait générer le fichier moc_* et devrait construire et lier correctement.

50
répondu MPicazo 2017-09-18 13:37:16

J'ai remarqué que certaines réponses sont basées sur Visual Studio.

Cette réponse est basée sur Qt Creator.

Contrairement au nom suggéré, Rebuild Project n'effacera pas tout et ne construira pas à partir de zéro. Si vous avez récemment ajouté QObject (et / ou Q_OBJECT) à votre classe, vous devrez à nouveau exécuter qmake, par exemple

  1. Projet Propre
  2. Exécuter qmake
  3. Construire Le Projet

C'est parce que, par défaut, qmake ne s'exécute que lorsque vous apportez des modifications significatives à votre solution comme ajouter de nouveaux fichiers source ou modifier le fichier .pro. Si vous modifiez un fichier existant, il ne sait pas qu'il doit exécuter qmake.

En guise de repli, pour forcer brutalement Qt à tout construire à partir de zéro, supprimez le dossier Debug ou Release.

25
répondu Stephen Quan 2018-09-11 22:14:07

Donc, le problème était que j'avais besoin du compilateur Qt MOC pour compiler mon .h fichier. Ceci est requis pour toutes les classes qui étendent QObject ou l'un de ses enfants. Le correctif a impliqué (pour moi) un clic droit sur le fichier d'en-tête, en choisissant les propriétés et en définissant le Type D'élément sur "Qt Moc Input", puis en appuyant sur "Compile" sur l'en-tête, puis en ajoutant le moc_myfilename résultant.fichier cpp à mon projet.

6
répondu Vern Jensen 2013-03-27 00:36:45

Si vos fichiers moc sont générés dans le projet visual studio, essayez de les inclure dans le projet s'ils ne le sont pas, puis reconstruisez.

6
répondu Akın Yılmaz 2014-12-25 12:13:39

J'ai eu le même problème dans Visual Studio, et l'ai résolu en procédant comme suit:

  1. Cliquez avec le bouton droit sur le fichier d'en-tête dans l'Explorateur de solutions
  2. Propriétés
  3. remplacez "Type D'élément" par "Outil de construction personnalisé"

Puis dans la configuration de L'outil de construction personnalisée:

  1. aller au général
  2. Définissez "ligne de commande" sur:

    " $(QTDIR)\bin \ moc.exe" "%(FullPath) "- o".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).rpc" "-fStdAfx.h" "-f../../../src / Nom du fichier.h" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_NETWORK_LIB -DWIN32_LEAN_AND_MEAN -DDIS_VERSION=7 -D_MATH_DEFINES_DEFINED "-I.\SFML_STATIC" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName).""-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtNetwork"

  3. Définit "sorties" sur:

    .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).rpc

  4. Définissez "dépendances supplémentaires"sur:
    $(QTDIR) \ bin\moc.exe;%(FullPath)


Vos valeurs exactes peuvent être différentes. Ils sont généralement appliqués via un plugin Qt.

5
répondu Trevor Hickey 2016-08-31 03:17:39

J'utilise CMake pour gérer les projets Qt et le nouveau Q_OBJECT doit être ajouté sous L'appel QT4_WRAP_CPP. Cela va générer le moc_*.cxx pour l'inclusion dans le projet et nettoyer les externes non résolus.

4
répondu whatnick 2013-10-28 03:16:04

J'ai eu ce problème avec Visual Studio 2012 quand j'avais une définition de classe Q_OBJECT dans mon fichier cpp. Le déplacement de la définition de classe vers le fichier d'en-tête a résolu le problème.

Il semble qu'il devrait être possible de prendre en charge la classe Q_OBJECT dans le fichier cpp en ajoutant le fichier cpp à moc mais je n'ai pas essayé cela.

2
répondu Edward 2016-05-18 09:18:15

J'ai ajouté manuellement des fichiers cpp/ui à mon projet, mais j'ai oublié d'ajouter explicitement le fichier d'en-tête en tant que Fichier d'en-tête. Maintenant, lors de la compilation, j'ai reçu un message d'erreur similaire à celui ci-dessus et le moc_*.les fichiers cpp n'ont pas été générés dans le répertoire debug (ou release) de la compilation. Ce n'était pas une erreur si évidente, qmake ne s'est pas plaint et autre que le message de l'éditeur de liens, Je n'ai eu aucune erreur.

Donc, si quelqu'un rencontre à nouveau le même problème (ou fait la même erreur copy & pase): Assurez-vous que le fichiers d'en-tête ont également été ajoutés à votre fichier de projet

2
répondu Vinoj John Hosan 2016-07-12 09:09:44

Dans mon cas (en utilisant QtAdd - in avec VS2012 et Qt v4. 8. 4) aucune des suggestions ci-dessus n'a fonctionné. Pour une raison quelconque, VS n'a pas pu générer les fichiers MOC appropriés (build output: aucune classe pertinente trouvée. Aucune sortie générée.) et quand j'ai compilé les en-têtes pertinents à la main (en définissant qt moc en tant que compilateur et en cliquant sur 'Compiler'), il a produit un fichier MOC vide.

Ce qui a fonctionné était de compiler tous les MOC nécessaires à partir de la ligne de commande (moc-o moc_SomeClass.rpc SomeClass.h) et puis remplacer les mauvais dans Dossier GeneratedFiles.

Ce n'est qu'une solution de contournement (et pas pratique pour un gros projet) pour que votre projet soit construit avec succès, mais n'explique pas vraiment le comportement étrange de VS/QtAdd-in.

1
répondu dianull 2013-07-10 09:31:06

En utilisant QtAdd - in avec VS2010 j'ai réalisé le moc_*.les fichiers cpp ont été mis à jour dans le dossier GeneratedFiles/Debug bien que j'étais en mode release. Copier les fichiers dans le dossier Release a fonctionné pour moi.

1
répondu zengaja 2014-01-22 08:22:07

J'ai eu ce problème avec une "classe privée". Qt utilise ce modèle bien que leur code. Je suis venu à vraiment aimer moi-même.

Fondamentalement, vous avez une classe déclarée en privé dans une définition de classe de fichier d'en-tête public, avec un pointeur vers une instance de celui-ci en tant que membre de données de la classe publique. (Note: vous pourriez trouver la vie plus facile de le déclarer comme une classe d'ami aussi.)

Ensuite, créez la version privée de votre classe dans le fichier cpp pour la version publique. Ne créez PAS de fichier d'en-tête pour cette classe privée. Faire tout le sale boulot avec cette classe. Cela cache toute la mise en œuvre de votre classe publique, y compris les autres membres privés.

Sans expliquer cela plus loin, voici le point en ce qui concerne ce fil. Pour obtenir le travail Q_OBJECT, j'avais besoin d'ajouter ceci au cpp:

#include "MyPublicClass.moc"

La mise en page cpp va comme ceci:

  1. La classe privée est définie
  2. le moc pour la classe publique est #inclus.
  3. alors la classe publique la mise en œuvre est définie.
0
répondu BuvinJ 2014-03-06 22:37:34

Cela m'est arrivé récemment lors du passage de MingW à MSVC. J'avais une classe/structure prototypée répertoriée en tant que classe, et MingW ne me dérangeait pas.

MSVC voit définitivement une différence entre class et struct lors du prototypage.

J'espère que ça aidera quelqu'un d'autre un jour.

0
répondu phyatt 2014-10-03 20:27:38

Dans mon cas, rien de ce qui précède n'a fonctionné mais c'était totalement mon erreur.

J'avais remplacé les fonctions virtuelles .h fichier (les a déclarés) mais ne les avait jamais définis .rpc :)

0
répondu zar 2015-02-19 16:35:05

J'ai résolu mon problème en ajoutant ceci à mon fichier d'en-tête :

#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H

... // all the header file content.

#endif
0
répondu Nadjib Dz 2016-01-11 14:36:17

L'une ou l'autre réponse fonctionne pour moi dans L'environnement VS 2013. Je résous finalement le problème en supprimant le .h / .cpp du projet, et en l'ajoutant.

0
répondu Adam Woo 2016-08-12 19:02:51

Je travaille dans VS2015 avec un client Perforce P4V intégré. Dans mon cas, Perforce a essayé d'ajouter un fichier moc à un depo, lorsque j'ai annulé cette opération, Perforce a supprimé ce fichier MOC du projet et l'a supprimé. Le fichier a été recréé après la prochaine compilation, mais il n'a pas été inclus dans le projet, je dois l'ajouter manuellement aux fichiers générés, quand j'ai finalement compris quel était le problème.

0
répondu Flot2011 2017-07-09 17:59:43

J'ai le même problème, ma solution était l'encodage( mon fichier avec "UTF16LE BOM" ne peut pas générer avec moc.exe), y créer un autre fichier avec encondage ASCII et cela fonctionne.

HXD HexEditor peut vous aider à voir la codification.

0
répondu Jefferson Rondan 2018-06-29 17:28:09

Je travaille dans VisualStudio uniquement avec un projet c++ doté D'une interface QT. Il suffit de supprimer la ligne Q_OBJECT fonctionne fines pour supprimer les erreurs de l'éditeur de liens. Ne semble pas avoir eu d'effet indésirable.

0
répondu Jan Laloux 2018-07-06 12:22:09

Je sais que c'est une question très ancienne, mais elle semble toujours intéressante (je suis ici au moins 4 ou 5 fois au cours des derniers mois) et semble avoir trouvé une autre raison pour laquelle il est possible d'obtenir cette erreur.

Dans mon cas, dans le fichier d'en-tête j'ai tort tapé:

#include "MyClass.h""

Ce n'est qu'après avoir inspecté toute la sortie que j'ai découvert qu'à cette ligne le compilateur émettait un avertissement.

Maintenant que j'ai supprimé le guillemet supplémentaire, mon QObject compile parfaitement!

0
répondu Brutus 2018-07-23 12:30:48

Pour moi, c'est la cause: un fichier d'en-tête ou source non inclus dans le fichier de projet de QT

0
répondu Sanbrother 2018-09-13 01:38:37