2012-12-23 24 views
29

私はプログラミングの初心者であり、プログラミングのためにコードブロックを使用しています。Qt未定義の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には次のように私は3つのファイルcommunicate.h、commmunicate.cppと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(); 
} 

とその上映エラーを次のように

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 ===| 

男を...それを把握...

+2

プロジェクトファイル(.PRO)は、ヘッダーセクション – Zeks

+0

でcommunicate.hファイルこれが重複しているが含まれていることを確認して、私が見つけた、そしてそれはここでは言及されていないではない、あまりにもローカライズされた –

+4

最良の答えはqmakeのを再実行する次のとおりです。http ://stackoverflow.com/a/3650758/258418 – ted

答えて

17

これは微妙なバグ(おそらく一部は、少なくともコンパイラのバグ)であることを傾ける助けてください私は以前見たことがあります。 QWidgetには仮想デストラクタがあるので、コンパイラにはクラスのvtableが必要です。しかし、あなたのクラスには仮想関数はありませんので、あなたのCommunicateクラス用にビルドしていません。

virtual ~Communicate() {};をクラスに追加すると、すべて正常に動作します。

はい、これを理解するまでには時間がかかりました。

+7

あなたは正しくありません。私はこのクラスをテストしたばかりです:クラスTest:public QObject {Q_OBJECT}これは、.proのヘッダファイルがあると仮定してコンパイルします。私はコメントアウトした時点でvtableへのundefinde参照を取得します – Zeks

+0

QTがまったく関与していなかった別のセットアップであり、問​​題はデストラクタが宣言されていないことが原因です。だから、MOCがこのようなことを「修正」しているのかもしれません。 –

+0

通信を追加すると、コードは正常にコンパイルされます。hをHEADERSセクションに追加します。 – Kikohs

4

デストラクタを定義する必要があります。 QObjectから派生しているにもかかわらず、コンパイラがデフォルトのコンストラクタ/デストラクタを使用するのに十分ではありません。

Qt Linker Error: "undefined reference to vtable"

+0

最後に!修正! – Shum

12

MOC(メタオブジェクトコンパイラ)がその仕事をする(他のQ_OBJECT'edクラスのと同様に)あなたのcommunicate.hを知っている必要があります。 HEADERSセクションの.proファイルに配置しない限り、この "未定義参照"を取得します。

+0

私はWindows 7でcodeblocksを使用しています。プロジェクトディレクトリを持つ.proファイルを見つけることはできません...もっと具体的にできますか? –

+0

@Zeksはい、あなたは正しいです、Qtもカスタムヘッダを知る必要があります – jondinham

18

問題を解決する簡単なオプションは、Q_OBJECTマクロを削除することです。これにより、アプリケーションのコンパイルとテストが可能になります。 、 しかし、正しい選択ではない、QTで毎日CBで作業する場合は、環境を設定する必要があります。

個人的には私がもっと好きで、カスタムメークファイルとファイルを作成するという選択肢が1つあります。アプリケーションの "pro"は、 "QtCreator" "NetBeansIDE"などの他の環境で容易に転送可能です。

私はすぐに何をするべきか説明します。 QtCreatorをインストールしている場合は、QtCreatorファイルで自己生成のサポートを受けるに値するし、少し経験すると自分のファイルを構築することができます。

この例あとで

  • 作業環境をカスタマイズする必要がありますあなたは「ターゲットリリース」下のファイルをコンパイルして実行するだけを許可するファイルを作成します。の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 "[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: 


  • プロジェクトファイルを作成します。Communicate.pro


QT  += core gui 

TARGET = Communicate 
TEMPLATE = app 


SOURCES += main.cpp\ 
     communicate.cpp 

HEADERS += communicate.h 


  • セットアップカスタムMakefileを...プロジェクト - >プロパティ:

Setup Makefile

  • セットアップファイル名を指定して実行アクション...プロジェクト - >プロパティ:

Set run action

  • 実行

Run

そのCBはwxWidgetsのでの作業に最適な環境であり、一般的にはC/C++が、私は個人的にはQtでの作業の場合には、QtCreatorはあなたで動作するように、よりネイティブと最適化された開発環境を提供することを考えますプロジェクトQT。

関連する問題