c++ - for - undefined reference to vtable qt
Qt referencia no definida a vtable (4)
Este es un error sutil (y probablemente parcialmente al menos un error de compilación) que he visto antes. Como QWidget tiene un destructor virtual, el compilador necesita un vtable para su clase. Pero su clase no tiene funciones virtuales, por lo que no creó una para su clase de Comunicar.
Agregue un virtual ~Communicate() {};
a su clase, y todo estará bien.
Sí, me tomó algo de tiempo resolver esto también!
Esta pregunta ya tiene una respuesta aquí:
Soy un principiante en la programación de Qt y uso bloques de código para mi programación. Creé 3 archivos communica.h, commmunicate.cpp y main.cpp de la siguiente manera:
communica.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();
}
y muestra errores de la siguiente manera:
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 ===|
chicos por favor ayuda ... no puedo entenderlo ...
MOC (compilador de metaobjetos) necesita saber de su communication.h (así como de cualquier otra clase Q_OBJECT''ed) para hacer su trabajo. A menos que los coloque en el archivo .pro en la sección HEADERS, obtendrá esta "referencia indefinida"
Necesitas definir el destructor. Aunque se deriva de un QObject, no es suficiente que el compilador use constructor / destructores predeterminados.
Una opción rápida para resolver el problema es eliminar la macro Q_OBJECT , esto le permitirá compilar y probar su aplicación, pero, no es una elección correcta , si tiene la intención de trabajar todos los días con QT, CB debe configurar su entorno.
Una opción que personalmente me gusta más y creo un archivo MAKE personalizado y un archivo. "pro" para la aplicación, es fácilmente transportable en otros entornos como "QtCreator", "NetBeansIDE", etc.
Explicaré rápidamente cuáles son los pasos a seguir. Si ha instalado QtCreator merece soporte autogenerado por el archivo QtCreator, y con un poco de experiencia puede construir sus propios archivos.
Este ejemplo solo le permite compilar y ejecutar los archivos en "Lanzamiento de destino" más adelante deberá personalizar su entorno de trabajo
- Crear archivo: 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:
- Crear archivo de proyecto: Communicate.pro
QT += core gui
TARGET = Communicate
TEMPLATE = app
SOURCES += main.cpp/
communicate.cpp
HEADERS += communicate.h
- Configurar Makefile personalizado ... Proyecto-> propiedades:
- Configuración Ejecutar acción ... Proyecto-> propiedades:
- correr
Aunque ese CB es un entorno óptimo para trabajar con wxWidgets, y C / C ++ en general, personalmente creo que en el caso de trabajar con Qt, QtCreator proporciona un entorno de desarrollo más nativo y optimizado para trabajar con los proyectos QT.