Qt undefined reference to vtable

C++User InterfaceQt4Codeblocks

C++ Problem Overview


I am a beginner to Qt programming and use codeblocks for my programming. I created 3 files communicate.h,commmunicate.cpp and main.cpp as follows:

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

and its showing errors as follows:

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

guys please help...cant figure it out...

C++ Solutions


Solution 1 - C++

This is a subtle bug (and probably partly at least a compiler bug) that I've seen before. Since QWidget has a virtual destructor, the compiler needs a vtable for your class. But your class doesn't have any virtual functions, so it didn't build one for your Communicate class.

Add a virtual ~Communicate() {}; to your class, and all will be well.

Yes, it took me some time to figure this out too!

Solution 2 - C++

MOC(meta object compiler) needs to know of your communicate.h (as well as of any other Q_OBJECT'ed classes) to do its job. Unless you place them into .pro file under HEADERS section - you will get this "undefined reference"

Solution 3 - C++

A quick option to solve the problem is to remove the Q_OBJECT macro, this will allow you to compile and test your application, but, not a right choice, if you intend to work every day with QT on CB must configure your environment.

One option that I personally like more and create a custom makefile and a file. "pro" for the application it is easily transportable in other environments as "QtCreator" "NetBeansIDE", etc.

I'll quickly explain what are the steps to follow. If you have installed QtCreator deserves support of self-generated by QtCreator file, and with a little experience can build your own files.

This example only allow you to compile and run the files under "Target Release" later you will have to customize your work environment

  • Create file: 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:


  • Create Project file: Communicate.pro


QT       += core gui

TARGET = Communicate
TEMPLATE = app


SOURCES += main.cpp\
        communicate.cpp

HEADERS  += communicate.h


  • Setup Custom Makefile ...Project->properties:

Setup Makefile

  • Setup Run Action ...Project->properties:

Set run action

  • Run

Run

Although that CB is an optimal environment for working with wxWidgets, and C/C++ in general, I personally think that in the case of working with Qt, QtCreator provides a development environment more native and optimized to work with your projects QT.

Solution 4 - C++

You need to define the destructor. Even though it derives from a QObject it's not enough for the compiler to use default constructor/destructors.

https://stackoverflow.com/questions/2555816/qt-object-linker-problem-undefined-reverence-to-vtable

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionranger101View Question on Stackoverflow
Solution 1 - C++Mats PeterssonView Answer on Stackoverflow
Solution 2 - C++ZeksView Answer on Stackoverflow
Solution 3 - C++RTOSkitView Answer on Stackoverflow
Solution 4 - C++BlastcoreView Answer on Stackoverflow