2012-12-23 16 views
29

Ich bin ein Anfänger zu Qt Programmierung und Codeblocks für meine Programmierung verwenden. Ich habe 3 Dateien communicate.h, commmunicate.cpp und main.cpp wie folgt:Qt undefined Verweis auf vtable

communicate.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 

communicate.cpp

#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)); 
} 

main.cpp

#include "communicate.h" 

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

    Communicate window; 

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

    return app.exec(); 
} 

und seine zeigt Fehler wie folgt:

obj\Debug\main.o(.text$_ZN11CommunicateD1Ev[Communicate::~Communicate()]+0xb)||In function `ZN7QStringC1EPKc':| 
C:\Qt\4.4.3\include\QtCore\..\..\src\corelib\arch\qatomic_windows.h||undefined reference to `vtable for Communicate'| 
obj\Debug\main.o(.text$_ZN11CommunicateD1Ev[Communicate::~Communicate()]+0x17):C:\Qt\4.4.3\include\QtCore\..\..\src\corelib\arch\qatomic_windows.h||undefined reference to `vtable for Communicate'| 
obj\Debug\communicate.o(.text+0x172)||In function `ZN11CommunicateC2EP7QWidget':| 
E:\Project\cam2\communicate.cpp|5|undefined reference to `vtable for Communicate'| 
obj\Debug\communicate.o(.text+0x17e):E:\Project\cam2\communicate.cpp|5|undefined reference to `vtable for Communicate'| 
obj\Debug\communicate.o(.text+0x63a)||In function `ZN11CommunicateC1EP7QWidget':| 
E:\Project\cam2\communicate.cpp|5|undefined reference to `vtable for Communicate'| 
obj\Debug\communicate.o(.text+0x646):E:\Project\cam2\communicate.cpp|5|more undefined references to `vtable for Communicate' follow| 
||=== Build finished: 6 errors, 0 warnings ===| 

Jungs helfen bitte ... kann es nicht herausfinden ...

+2

stellen Sie sicher, dass Ihre Projektdatei (.pro) in Header Abschnitt communicate.h Datei enthält – Zeks

+0

Dies ist ein Duplikat ist, nicht zu lokalisierten –

+4

die beste Antwort, die ich gefunden, und dass erwähnt wird, ist nicht hier qmake erneut ausführen: http : //stackoverflow.com/a/3650758/258418 – ted

Antwort

17

Dies ist ein subtiler Fehler (und wahrscheinlich zumindest teilweise einen Compiler Fehler), dass Ich habe es schon mal gesehen. Da QWidget über einen virtuellen Destruktor verfügt, benötigt der Compiler eine vtable für Ihre Klasse. Ihre Klasse hat jedoch keine virtuellen Funktionen. Daher hat sie keine Klasse für Ihre Communicate-Klasse erstellt.

Fügen Sie Ihrer Klasse einen virtual ~Communicate() {}; hinzu, und alles wird gut.

Ja, es hat einige Zeit gedauert, das herauszufinden!

+7

Sie sind nicht korrekt. Ich habe gerade diese Klasse getestet: class Test: public QObject {Q_OBJECT} und kompiliert einfach gut unter der Annahme, Header-Datei befindet sich in .pro Der Moment, den ich es auskommen - ich bekomme den undefinierten Verweis auf vtable – Zeks

+0

Ok, ich habe dieses Problem in gesehen ein anderes Setup, bei dem QT überhaupt nicht beteiligt war, und das Problem wurde dadurch verursacht, dass kein Destruktor deklariert wurde. Kann es also sein, dass die MOC solche Dinge im laufenden Betrieb "repariert"? –

+0

Der Code wird ordnungsgemäß kompiliert, wenn Sie die Kommunikation hinzufügen.h im Abschnitt HEADERS. – Kikohs

12

MOC (Metaobjekt-Compiler) muss Ihre communicate.h (sowie alle anderen Q_OBJECT'ed Klassen) wissen, seine Arbeit zu tun. Es sei denn, Sie sie in .proDatei unter HEADERS Abschnitt platzieren - Sie werden diese „undefined reference“ get

+0

Ich verwende Codeblocks in Windows 7. Ich kann keine .pro-Datei mit dem Projektverzeichnis finden ... können Sie bitte genauer? –

+0

@Zeks ja du hast Recht, Qt muss auch die benutzerdefinierte Header kennen – jondinham

18

Eine schnelle Möglichkeit, das Problem zu lösen, ist zu die Q_OBJECT Makro zu entfernen, wird diese ermöglichen es Ihnen Ihre Anwendung zu kompilieren und testen , aber, keine richtige Wahl, wenn Sie jeden Tag mit QT auf CB arbeiten möchten, müssen Sie Ihre Umgebung konfigurieren.

Eine Option, die ich persönlich mehr mag und ein benutzerdefiniertes Makefile und eine Datei erstellen. "Pro" für die Anwendung ist es leicht in anderen Umgebungen als "QtCreator" "NetBeansIDE" usw. zu transportieren.

Ich werde schnell erklären, was die folgenden Schritte sind. Wenn Sie QtCreator installiert haben, verdient Unterstützung von selbst erstellten QtCreator-Datei, und mit ein wenig Erfahrung können Sie Ihre eigenen Dateien erstellen.Makefile


:

Dieses Beispiel können Sie nur die Dateien unter „Ziel-Release“ kompilieren und ausführen später werden Sie Ihre Arbeitsumgebung

  • Datei erstellen anpassen müssen

    ####### 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 "[email protected]" "$<" 
    
    .cc.o: 
        $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "[email protected]" "$<" 
    
    .cxx.o: 
        $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "[email protected]" "$<" 
    
    .C.o: 
        $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "[email protected]" "$<" 
    
    .c.o: 
        $(CC) -c $(CFLAGS) $(INCPATH) -o "[email protected]" "$<" 
    
    ####### 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: 
    


    • erstellen Projektdatei: Communicate.pro


    QT  += core gui 
    
    TARGET = Communicate 
    TEMPLATE = app 
    
    
    SOURCES += main.cpp\ 
         communicate.cpp 
    
    HEADERS += communicate.h 
    


    • -Setup Benutzerdefinierte Makefile ... Ausbau-> Eigenschaften:

    Setup Makefile

    • Setup-Run Aktion ... Ausbau-> Eigenschaften:

    Set run action

    • Run

    Run

    Obwohl die CB für die Arbeit mit wxWidgets eine optimale Umgebung ist, und C/C++ im Allgemeinen, ich persönlich denke, dass mit Qt im Fall arbeiten, QtCreator eine mit Ihrer Arbeit Entwicklungsumgebung mehr einheimischen und optimierte bietet Projekte QT.

Verwandte Themen