55 votes

Référence indéfinie à vtable. Essayer de compiler un projet Qt

J'utilise Code::Blocks 8.02 et le compilateur mingw 5.1.6. J'obtiens cette erreur lorsque je compile mon projet Qt :

C:\Documents et paramètres \The Fuzz \Desktop\GUI\App_interface.cpp |33|indéfini référence à `vtable for AddressBook'.

Fichier AddressBook.h :

 #ifndef ADDRESSBOOK_H
 #define ADDRESSBOOK_H

 #include <QWidget>

 class QLabel;
 class QLineEdit;
 class QTextEdit;

 class AddressBook : public QWidget
 {
     Q_OBJECT

 public:
     AddressBook(QWidget *parent = 0);

 private:
     QLineEdit *nameLine;
     QTextEdit *addressText;
 };

 #endif

Fichier AddressBook.cpp :

#include <QtGui>
#include "addressbook.h"

AddressBook::AddressBook(QWidget *parent)
     : QWidget(parent)
{
    QLabel *nameLabel = new QLabel(tr("Name:"));
    nameLine = new QLineEdit;

    QLabel *addressLabel = new QLabel(tr("Address:"));
    addressText = new QTextEdit;

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(nameLabel, 0, 0);
    mainLayout->addWidget(nameLine, 0, 1);
    mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
    mainLayout->addWidget(addressText, 1, 1);

    setLayout(mainLayout);
    setWindowTitle(tr("Simple Address Book"));
}

51voto

Anurag Verma Points 101

Lorsque vous utilisez Qt Creator :

  1. Build → Exécuter qmake
  2. Construire → Reconstruire tout

2 votes

Cette réponse est trompeuse. Elle est parfaitement logique si le PO utilise Qt Creator, mais le PO ne mentionne que Code::Blocks. À ma connaissance, Code::Blocks n'est pas livré avec une version de exécuter qmake sur le menu de construction, et pourquoi le ferait-elle ? Je peux croire qu'un plugin ajouterait une option comme celle-là, mais l'OP ne mentionne pas l'utilisation d'un plugin tiers. Il est probable que l'OP doit toujours utiliser qmake mais lui dire d'utiliser une option de menu qui n'existe probablement pas ne va pas l'aider.

0 votes

Correct, la solution (lorsqu'on n'utilise pas Creator) est de simplement exécuter qmake à partir d'une invite de commande.

0 votes

Lancez qmake et ensuite make pour obtenir l'effet exact - lancer make génère seulement le fichier make. Un nom plutôt trompeur, en fait.

47voto

blwy10 Points 2858

Avertissement : Ne faites pas cela si vous avez déjà un fichier .pro - vous le perdrez !

Afin de s'assurer automatiquement que tous les fichiers moc cpp sont générés, vous pouvez demander à qmake de générer automatiquement un fichier .pro pour vous au lieu d'en écrire un vous-même.

Exécuter

qmake -project

dans le répertoire du projet, et qmake analysera votre répertoire à la recherche de tous les en-têtes et fichiers sources C++ pour lesquels générer des fichiers moc cpp.

3 votes

J'ai exactement le même problème que le PO, mais dans mon cas, réexécuter qmake ne le résout pas. Ce n'est qu'une solution partielle qui ne fonctionnera que pour certains.

1 votes

DarenW : Vérifiez que l'en-tête contenant la déclaration de la classe est répertorié dans HEADERS.

1 votes

DarenW : merci, ça aide. j'ai réfléchi à ce problème pendant 3 heures. qu'est-ce que c'est ? je n'ai pas écrit qmake manuellement. est-ce un trou dans qt, ou quoi ? pourquoi ne compile-t-il pas, alors que nous avons tout écrit correctement ?

16voto

Le problème est très certainement que vous ne compilez pas ou ne liez pas le fichier moc_AddressBook.cpp généré. (Il aurait dû être généré pour vous -- vous exécutez la version de Qt moc sur votre code avant de compiler, n'est-ce pas ?)

Pour répondre de manière un peu plus approfondie, le Q_OBJECT signale à la macro de Qt moc pour créer un fichier d'implémentation supplémentaire contenant le code nécessaire à la prise en charge de l'outil QObject Le système de méta-information de la Commission européenne. Si vous avez des signaux ou des créneaux, il peut aussi faire quelques choses pour eux.

Une solution alternative pourrait consister à supprimer le Q_OBJECT macro. Vous ne voulez probablement pas faire cela, mais cela aiderait le problème immédiat, et ce n'est pas strictement nécessaire avec le code que vous avez présenté.

De plus, je note que votre ligne :

#include "addressbook.h"

Ça devrait probablement l'être :

#include "AddressBook.h"

en fonction de la façon dont vous avez présenté les noms de fichiers dans la question.

0 votes

Les systèmes de fichiers Windows ne sont pas sensibles à la casse.

12 votes

Vous devriez quand même essayer de faire attention à la casse même sous Windows... C'est vraiment ennuyeux sous Unix de vérifier un projet et de devoir corriger manuellement les problèmes de casse comme celui-ci parce que le développeur original sous Windows ne s'en est pas soucié.

9voto

Jeremy Friesner Points 16684

En supposant que vous utilisez qmake pour générer votre Makefile, assurez-vous que AddressBook.h est spécifié dans la variable HEADERS de votre fichier .pro, e.g.

HEADERS = AddressBook.h

0 votes

Réponse réelle à cette question, sans discussions ou causes spécifiques à la plate-forme ou à la cause, claire et utilisable. Merci.

0 votes

Avec QTCreator, vous utilisez la section "Headers" du projet et y ajoutez votre fichier (il l'ajoute à la variable HEADERS dans le .pro).

0 votes

QtCreator peut ajouter le nom de votre fichier d'en-tête sur la deuxième ligne de la variable HEADERS dans votre fichier .pro. La première ligne serait alors "HEADERS += \". Cela ne fonctionnera pas. Effacez la première entrée vide et transformez-la (dans le cas du PO) en : "HEADERS += AddressBook.h"

4voto

Jesse Victors Points 41

J'ai obtenu ce résultat en utilisant des fonctions virtuelles pures. Par exemple,

virtual void process();

a donné cette erreur, alors que

virtual void process() = 0;

l'a fait disparaître.

Pour tous ceux qui recherchent ce problème sur Google, vérifiez que toutes les fonctions virtuelles sont définies. (via " = 0" ou une définition complète dans le fichier source). J'utilise Netbeans avec le compilateur MinGW.

0 votes

J'avais le même problème avec Qt Creator 1.3 sous Ubuntu, et ceci a fonctionné pour moi. Je ne sais pas quel est le problème sous-jacent, cependant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X