看起来如此主要的错误.cpp:(.text.startup+0xd6):未定义对"vtable for Counter"的引用?

ERROR that looks so main.cpp:(.text.startup+0xd6): undefined reference to `vtable for Counter'?

本文关键字:未定义 引用 vtable for Counter text 错误 看起来 cpp startup+0xd6      更新时间:2023-10-16

我有一个自然微不足道的问题,因为我的意思是:我们按下按钮 ->计数器增加,计数器增加 ->QLabel的价值更新。我发现了奇怪的错误,不想这样做。我在C++不是假人,但在QT中我是。这是我在其中的第一个也是最琐碎的应用程序。

那里的一些答案(在堆栈溢出上(建议添加虚拟构造函数。它没有效果。

试图将信号和插槽重写为新的 qt5 样式,但还有其他问题,我懒得修复它们,这是(重写,而不是懒惰:)(是一种好方法,也许问题真的出在版本上?

我只是没有尝试重新安装QT或安装Qt4,也许问题出在里面?

关于版本:

$ qmake --version

响应:

QMake version 3.0
Using Qt version 5.5.1 in /usr/lib/x86_64-linux-gnu

conn.pro:

TEMPLATE = app
QT += core gui
TARGET = conn
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
SOURCES += main.cpp

主.cpp:

#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QObject>
class Counter : public QObject {
    Q_OBJECT
private:
    double i_;
public:
    virtual ~Counter()
    {
    }
    Counter() : QObject(), i_(0)
    {
    }

public slots:
    void slot_incCounter();
signals:
    void goodbye(){}
    void counterChanged(double){}
};
void Counter::slot_incCounter() {
    emit counterChanged(++i_);
    if (i_ == 5) {
        emit goodbye();
    }
}
int main(int argc, char* argv[]) {
    QApplication my_app(argc, argv);
    QLabel label1("label i created");
    label1.show();
    QPushButton button1("press me");
    button1.show();
    Counter counter1;
    QObject::connect(&button1, SIGNAL(clicked()),
                     &counter1, SLOT(slot_incCounter()));
    QObject::connect(&counter1, SIGNAL(counterChanged(double a)),
                     &label1, SLOT(setNum(double a)));
    QObject::connect(&counter1, SIGNAL(goodbye()),
                     &my_app, SLOT(quit()));
    return my_app.exec();
}

尝试运行它:

qmake && make && ./conn 

所以我在控制台中看到:

g++ -m64 -Wl,-O1 -o conn main.o   -L/usr/X11R6/lib64 -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread 
main.o: In function `main':
main.cpp:(.text.startup+0xd6): undefined reference to `vtable for Counter'
collect2: error: ld returned 1 exit status
Makefile:144: recipe for target 'conn' failed
make`:` *** [conn] Error 1

我该怎么办?

Qt使用元对象编译器(MOC(来启用信号和插槽等。默认情况下,如果Q_OBJECT宏位于头文件中,则它可以完美运行。所以最简单的方法是你把Counter放到它自己的头/实现文件中,重新运行qmakemake。(顺便说一下,这是好的做法...

如果要坚持使用单个主文件.cpp则需要明确告诉 moc 此文件包含 moc 需要解析的宏。您可以在 main.cpp 的最末尾使用以下行执行此操作:

#include "main.moc"

然后还要重新运行qmakemake

请记住,手动包含 moc-include 指令不是最佳选择。因此,最好从一开始就将C++类拆分为单独的文件......

非常感谢!你的回答是完整的,有用的,使一切更加明显。解决方案是:1. 将类计数器移动到计数器.h从这一刻起,关于 vtable 的消息消失了。出现的消息,告别((和计数器::计数器更改(双精度(具有多个定义。第一个定义是我在Counter.cpp(错误的方式(中的定义。第二个是在moc_Counter.cpp,由MOC实用程序生成。所以:

2. 删除信号函数的定义(我的空定义(,因为 moc 在文件moc_Counter.cpp中有自己的定义:

// SIGNAL 0
void Counter::goodbye()
{
    QMetaObject::activate(this, &staticMetaObject, 0, Q_NULLPTR);
}
// SIGNAL 1
void Counter::counterChanged(double _t1)
{
    void *_a[] = { Q_NULLPTR, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, &staticMetaObject, 1, _a);
}

它们会导致多重定义的问题。

总结一下,工作代码:

主.cpp:

#include <QApplication>
#include "Counter.h"

int main(int argc, char* argv[]) {
    QApplication my_app(argc, argv);
    QLabel label1("1");
    label1.show();
    QPushButton button1("press me");
    button1.show();
    Counter counter1;
    QObject::connect(&button1, SIGNAL(clicked()),
                     &counter1, SLOT(slot_incCounter()));
    QObject::connect(&counter1, SIGNAL(counterChanged(double)),
                     &label1, SLOT(setNum(double)));
    QObject::connect(&counter1, SIGNAL(goodbye()),
                     &my_app, SLOT(quit()));
    return my_app.exec();
}

void Counter::slot_incCounter() {
    emit counterChanged(++i_);
    if (i_ == 5) {
        emit goodbye();
    }
}

计数器:

#ifndef COUNTER_H
#define COUNTER_H
#include <QLabel>
#include <QPushButton>
#include <QObject>
class Counter : public QObject {
    Q_OBJECT
private:
    double i_;
public:
    virtual ~Counter()
    {
    }
    Counter() : QObject()
    {
    }

public slots:
    void slot_incCounter();
signals:
    void goodbye();
    void counterChanged(double);
};
#endif // COUNTER_H

计数器.cpp:

#include "Counter.h"

谢谢,你很棒!