Qt référence indéfinie à vtable [dupliquer]

Cette question a déjà une réponse ici:

Je suis un débutant en programmation Qt et utilise des codeblocks pour ma programmation. J'ai créé 3 fichiers communiquer.h, commmunicate.cpp et principal.le rpc suit:

Communiquer.h

    #ifndef COMMUNICATE_H
    #define COMMUNICATE_H

    #include <QWidget>
    #include <QApplication>
    #include <QPushButton>
    #include <QLabel>

    class Communicate : public QWidget
    {
      Q_OBJECT

      public:
        Communicate(QWidget *parent = 0);


      private slots:
        void OnPlus();
        void OnMinus();

      private:
        QLabel *label;

    };

    #endif

Communiquer.rpc

#include "communicate.h"

Communicate::Communicate(QWidget *parent)
    : QWidget(parent)
{
  QPushButton *plus = new QPushButton("+", this);
  plus->setGeometry(50, 40, 75, 30);

  QPushButton *minus = new QPushButton("-", this);
  minus->setGeometry(50, 100, 75, 30);

  label = new QLabel("0", this);
  label->setGeometry(190, 80, 20, 30);

  connect(plus, SIGNAL(clicked()), this, SLOT(OnPlus()));
  connect(minus, SIGNAL(clicked()), this, SLOT(OnMinus()));
}

void Communicate::OnPlus()
{
  int val = label->text().toInt();
  val++;
  label->setText(QString::number(val));
}

void Communicate::OnMinus()
{
  int val = label->text().toInt();
  val--;
  label->setText(QString::number(val));
}

Principal.rpc

#include "communicate.h"

int main(int argc, char *argv[])
{
  QApplication app(argc, argv);

  Communicate window;

  window.setWindowTitle("Communicate");
  window.show();

  return app.exec();
}

Et ses erreurs d'affichage comme suit:

objDebugmain.o(.text$_ZN11CommunicateD1Ev[Communicate::~Communicate()]+0xb)||In function `ZN7QStringC1EPKc':|
C:Qt4.4.3includeQtCore....srccorelibarchqatomic_windows.h||undefined reference to `vtable for Communicate'|
objDebugmain.o(.text$_ZN11CommunicateD1Ev[Communicate::~Communicate()]+0x17):C:Qt4.4.3includeQtCore....srccorelibarchqatomic_windows.h||undefined reference to `vtable for Communicate'|
objDebugcommunicate.o(.text+0x172)||In function `ZN11CommunicateC2EP7QWidget':|
E:Projectcam2communicate.cpp|5|undefined reference to `vtable for Communicate'|
objDebugcommunicate.o(.text+0x17e):E:Projectcam2communicate.cpp|5|undefined reference to `vtable for Communicate'|
objDebugcommunicate.o(.text+0x63a)||In function `ZN11CommunicateC1EP7QWidget':|
E:Projectcam2communicate.cpp|5|undefined reference to `vtable for Communicate'|
objDebugcommunicate.o(.text+0x646):E:Projectcam2communicate.cpp|5|more undefined references to `vtable for Communicate' follow|
||=== Build finished: 6 errors, 0 warnings ===|

Les gars s'il vous plaît aider...ne peux pas comprendre ce...

29
demandé sur Yu Hao 2012-12-23 16:26:42

4 réponses

C'est un bug subtil (et probablement en partie au moins un bug du compilateur) que j'ai déjà vu. Puisque QWidget a un destructeur virtuel, le compilateur a besoin d'une vtable pour votre classe. Mais votre classe n'a pas de fonctions virtuelles, donc elle n'en a pas construit une pour votre classe Communicate.

Ajouter un virtual ~Communicate() {}; à votre classe, et tout ira bien.

Oui, il m'a fallu du temps pour comprendre cela aussi!

24
répondu Mats Petersson 2012-12-23 12:33:10

Une option rapide pour résoudre le problème est de supprimer la macro Q_OBJECT , cela vous permettra de compiler et de tester votre application, mais, pas un bon choix, si vous avez l'intention de travailler tous les jours avec QT sur l'OC doit configurer votre environnement.

Une option que j'aime personnellement plus et créer un makefile personnalisé et un fichier. "pro" pour l'application, il est facilement transportable dans d'autres environnements comme "QtCreator" "NetBeansIDE", etc.

Je vais vite expliquer quelles sont les étapes à suivre. Si vous avez installé QtCreator mérite le soutien de l'auto-généré par le fichier QtCreator, et avec un peu d'expérience peut construire vos propres fichiers.

cet exemple vous permet uniquement de compiler et d'exécuter les fichiers sous" Version cible " plus tard, vous devrez personnaliser votre environnement de travail

  • Créer un fichier: Makefile


####### Compiler, tools and options

PROJECT_NAME  = Communicate
QT_INCLUDE    = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/include/
QT_MKSPECS    = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/mkspecs/
QT_LIB        = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/lib
QT_QMAKE      = /usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/bin/
CC            = gcc
CXX           = g++
DEFINES       = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS        = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)
CXXFLAGS      = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES)
INCPATH       = -I$(QT_MKSPECS)linux-g++ -I../$(PROJECT_NAME) -I$(QT_INCLUDE)QtCore -I$(QT_INCLUDE)QtGui -I/usr/local/QtSDK/Desktop/Qt/4.8.1/gcc/include -I. -I../$(PROJECT_NAME) -I.
LINK          = g++
LFLAGS        = -Wl,-O1 -Wl,-rpath,$(QT_LIB)
LIBS          = $(SUBLIBS)  -L$(QT_LIB) -lQtGui -L$(QT_LIB) -L/usr/X11R6/lib -lQtCore -lpthread 
AR            = ar cqs
RANLIB        = 
QMAKE         = $(QT_QMAKE)qmake
TAR           = tar -cf
COMPRESS      = gzip -9f
COPY          = cp -f
SED           = sed
COPY_FILE     = $(COPY)
COPY_DIR      = $(COPY) -r
STRIP         = strip
INSTALL_FILE  = install -m 644 -p
INSTALL_DIR   = $(COPY_DIR)
INSTALL_PROGRAM = install -m 755 -p
DEL_FILE      = rm -f
SYMLINK       = ln -f -s
DEL_DIR       = rmdir
MOVE          = mv -f
CHK_DIR_EXISTS= test -d
MKDIR         = mkdir -p

####### Output directory

OBJECTS_DIR   = ./Release

####### Files

SOURCES       = ../$(PROJECT_NAME)/main.cpp \
        ../$(PROJECT_NAME)/communicate.cpp moc_communicate.cpp
OBJECTS       = main.o \
        communicate.o \
        moc_communicate.o
DIST          = $(QT_MKSPECS)common/unix.conf \
        $(QT_MKSPECS)common/linux.conf \
        $(QT_MKSPECS)common/gcc-base.conf \
        $(QT_MKSPECS)common/gcc-base-unix.conf \
        $(QT_MKSPECS)common/g++-base.conf \
        $(QT_MKSPECS)common/g++-unix.conf \
        $(QT_MKSPECS)qconfig.pri \
        $(QT_MKSPECS)modules/qt_webkit_version.pri \
        $(QT_MKSPECS)features/qt_functions.prf \
        $(QT_MKSPECS)features/qt_config.prf \
        $(QT_MKSPECS)features/exclusive_builds.prf \
        $(QT_MKSPECS)features/default_pre.prf \
        $(QT_MKSPECS)features/release.prf \
        $(QT_MKSPECS)features/default_post.prf \
        $(QT_MKSPECS)features/unix/gdb_dwarf_index.prf \
        $(QT_MKSPECS)features/warn_on.prf \
        $(QT_MKSPECS)features/qt.prf \
        $(QT_MKSPECS)features/unix/thread.prf \
        $(QT_MKSPECS)features/moc.prf \
        $(QT_MKSPECS)features/resources.prf \
        $(QT_MKSPECS)features/uic.prf \
        $(QT_MKSPECS)features/yacc.prf \
        $(QT_MKSPECS)features/lex.prf \
        $(QT_MKSPECS)features/include_source_dir.prf \
        ../$(PROJECT_NAME)/$(PROJECT_NAME).pro
QMAKE_TARGET  = $(PROJECT_NAME) Release
DESTDIR       = $(OBJECTS_DIR)
TARGET        = $(PROJECT_NAME)

first: all
####### Implicit rules

.SUFFIXES: .o .c .cpp .cc .cxx .C

.cpp.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.cc.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.cxx.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.C.o:
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.c.o:
    $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"

####### Build rules

all: Makefile $(TARGET)

$(TARGET):  $(OBJECTS)  
    $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)

Makefile: ../$(PROJECT_NAME)/$(PROJECT_NAME).pro  $(QT_MKSPECS)linux-g++/qmake.conf $(QT_MKSPECS)common/unix.conf \
        $(QT_MKSPECS)common/linux.conf \
        $(QT_MKSPECS)common/gcc-base.conf \
        $(QT_MKSPECS)common/gcc-base-unix.conf \
        $(QT_MKSPECS)common/g++-base.conf \
        $(QT_MKSPECS)common/g++-unix.conf \
        $(QT_MKSPECS)qconfig.pri \
        $(QT_MKSPECS)modules/qt_webkit_version.pri \
        $(QT_MKSPECS)features/qt_functions.prf \
        $(QT_MKSPECS)features/qt_config.prf \
        $(QT_MKSPECS)features/exclusive_builds.prf \
        $(QT_MKSPECS)features/default_pre.prf \
        $(QT_MKSPECS)features/release.prf \
        $(QT_MKSPECS)features/default_post.prf \
        $(QT_MKSPECS)features/unix/gdb_dwarf_index.prf \
        $(QT_MKSPECS)features/warn_on.prf \
        $(QT_MKSPECS)features/qt.prf \
        $(QT_MKSPECS)features/unix/thread.prf \
        $(QT_MKSPECS)features/moc.prf \
        $(QT_MKSPECS)features/resources.prf \
        $(QT_MKSPECS)features/uic.prf \
        $(QT_MKSPECS)features/yacc.prf \
        $(QT_MKSPECS)features/lex.prf \
        $(QT_MKSPECS)features/include_source_dir.prf \
        $(QT_LIB)/libQtGui.prl \
        $(QT_LIB)/libQtCore.prl
    $(QMAKE) -spec $(QT_MKSPECS)linux-g++ -o Makefile ../$(PROJECT_NAME)/$(PROJECT_NAME).pro
$(QT_MKSPECS)common/unix.conf:
$(QT_MKSPECS)common/linux.conf:
$(QT_MKSPECS)common/gcc-base.conf:
$(QT_MKSPECS)common/gcc-base-unix.conf:
$(QT_MKSPECS)common/g++-base.conf:
$(QT_MKSPECS)common/g++-unix.conf:
$(QT_MKSPECS)qconfig.pri:
$(QT_MKSPECS)modules/qt_webkit_version.pri:
$(QT_MKSPECS)features/qt_functions.prf:
$(QT_MKSPECS)features/qt_config.prf:
$(QT_MKSPECS)features/exclusive_builds.prf:
$(QT_MKSPECS)features/default_pre.prf:
$(QT_MKSPECS)features/release.prf:
$(QT_MKSPECS)features/default_post.prf:
$(QT_MKSPECS)features/unix/gdb_dwarf_index.prf:
$(QT_MKSPECS)features/warn_on.prf:
$(QT_MKSPECS)features/qt.prf:
$(QT_MKSPECS)features/unix/thread.prf:
$(QT_MKSPECS)features/moc.prf:
$(QT_MKSPECS)features/resources.prf:
$(QT_MKSPECS)features/uic.prf:
$(QT_MKSPECS)features/yacc.prf:
$(QT_MKSPECS)features/lex.prf:
$(QT_MKSPECS)features/include_source_dir.prf:
$(QT_LIB)/libQtGui.prl:
$(QT_LIB)/libQtCore.prl:
qmake:  FORCE
    @$(QMAKE) -spec $(QT_MKSPECS)linux-g++ -o Makefile ../$(PROJECT_NAME)/$(PROJECT_NAME).pro

dist: 
    @$(CHK_DIR_EXISTS) .tmp/$(PROJECT_NAME)1.0.0 || $(MKDIR) .tmp/$(PROJECT_NAME)1.0.0 
    $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/$(PROJECT_NAME)1.0.0/ && $(COPY_FILE) --parents ../$(PROJECT_NAME)/communicate.h .tmp/$(PROJECT_NAME)1.0.0/ && $(COPY_FILE) --parents ../$(PROJECT_NAME)/main.cpp ../$(PROJECT_NAME)/communicate.cpp .tmp/$(PROJECT_NAME)1.0.0/ && (cd `dirname .tmp/$(PROJECT_NAME)1.0.0` && $(TAR) $(PROJECT_NAME)1.0.0.tar $(PROJECT_NAME)1.0.0 && $(COMPRESS) $(PROJECT_NAME)1.0.0.tar) && $(MOVE) `dirname .tmp/$(PROJECT_NAME)1.0.0`/$(PROJECT_NAME)1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/$(PROJECT_NAME)1.0.0


clean:compiler_clean 
    -$(DEL_FILE) $(OBJECTS)
    -$(DEL_FILE) *~ core *.core


####### Sub-libraries

distclean: clean
    -$(DEL_FILE) $(TARGET) 

#-$(DEL_FILE) Makefile


check: first

mocclean: compiler_moc_header_clean compiler_moc_source_clean

mocables: compiler_moc_header_make_all compiler_moc_source_make_all

compiler_moc_header_make_all: moc_communicate.cpp
compiler_moc_header_clean:
    -$(DEL_FILE) moc_communicate.cpp
moc_communicate.cpp: ../$(PROJECT_NAME)/communicate.h
    $(QT_QMAKE)moc $(DEFINES) $(INCPATH) ../$(PROJECT_NAME)/communicate.h -o moc_communicate.cpp

compiler_rcc_make_all:
compiler_rcc_clean:
compiler_image_collection_make_all: qmake_image_collection.cpp
compiler_image_collection_clean:
    -$(DEL_FILE) qmake_image_collection.cpp
compiler_moc_source_make_all:
compiler_moc_source_clean:
compiler_uic_make_all:
compiler_uic_clean:
compiler_yacc_decl_make_all:
compiler_yacc_decl_clean:
compiler_yacc_impl_make_all:
compiler_yacc_impl_clean:
compiler_lex_make_all:
compiler_lex_clean:
compiler_clean: compiler_moc_header_clean 

####### Compile

main.o: ../$(PROJECT_NAME)/main.cpp ../$(PROJECT_NAME)/communicate.h
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o ../$(PROJECT_NAME)/main.cpp

communicate.o: ../$(PROJECT_NAME)/communicate.cpp ../$(PROJECT_NAME)/communicate.h
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o communicate.o ../$(PROJECT_NAME)/communicate.cpp

moc_communicate.o: moc_communicate.cpp 
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_communicate.o moc_communicate.cpp

####### Install

install:   FORCE

uninstall:   FORCE

FORCE:


  • créer un fichier de projet: Communicate.pro


QT       += core gui

TARGET = Communicate
TEMPLATE = app


SOURCES += main.cpp\
        communicate.cpp

HEADERS  += communicate.h


  • Configuration Du Makefile Personnalisé ...Projet - > Propriétés:

Configuration Makefile

  • Action D'Exécution Du Programme D'Installation ...Projet - > Propriétés:

Définir l'action Exécuter

  • Exécuter

Exécuter

Bien que CB soit un environnement optimal pour travailler avec wxWidgets, et C / C++ en général, je pense personnellement que dans le cas de travailler avec Qt, QtCreator fournit un développement environnement plus natif et optimisé pour travailler avec vos projets QT.

19
répondu RTOSkit 2012-12-23 17:51:36

MOC (meta object compiler) doit connaître votre communication.h (ainsi que de toutes les autres classes Q_OBJECT'ED) pour faire son travail. Sauf si vous les placez dans le fichier. pro sous la section HEADERS-vous obtiendrez cette "référence indéfinie"

14
répondu Zeks 2012-12-23 12:46:22

Vous devez définir le destructeur. Même s'il dérive d'un QObject, il ne suffit pas que le compilateur utilise le constructeur/destructeur par défaut.

Erreur de L'éditeur de liens Qt: "référence indéfinie à vtable"

4
répondu Blastcore 2017-05-23 12:18:17