看起来如此 main.cpp:(.text.startup+0xd6): undefined reference to `vtable for Counter' 的错误?

Posted

技术标签:

【中文标题】看起来如此 main.cpp:(.text.startup+0xd6): undefined reference to `vtable for Counter\' 的错误?【英文标题】:ERROR that looks so main.cpp:(.text.startup+0xd6): undefined reference to `vtable for Counter'?看起来如此 main.cpp:(.text.startup+0xd6): undefined reference to `vtable for Counter' 的错误? 【发布时间】:2017-05-27 21:13:58 【问题描述】:

我的意思是自然而然的小问题:我们按下按钮 --> 计数器增加,计数器增加 --> QLabel 的值被更新。我发现了奇怪的错误,不想这样做。我在 C++ 中不是傻瓜,但在 QT 中我是。这是我第一个也是最简单的应用程序。

那里的一些答案(在 Stack Overflow 上)建议添加虚拟构造函数。它没有效果。

我尝试将信号和插槽重写为新的 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

ma​​in.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

我该怎么办?

【问题讨论】:

【参考方案1】:

Qt 使用元对象编译器 (moc) 来启用例如信号和插槽。默认情况下,如果 Q_OBJECT 宏在头文件中,它会完美运行。所以最简单的方法是将Counter 放入它自己的头文件/实现文件中,重新运行qmakemake。 (顺便说一句,这是一种很好的做法......)

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

#include "main.moc"

然后也重新运行qmakemake

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

【讨论】:

将其移至 .h 作品。没有尝试第二种方法。感谢您的完整回答!【参考方案2】:

非常感谢!您的回答是完整的,有用的,并且使一切变得更加明显。 解决方案是: 1。将类 Counter 移至 Counter.h 从这一刻起,关于 vtable 的消息就消失了。出现 goodbye() 和 Counter::counterChanged(double) 有多重定义的消息。第一个定义是我在 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);

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

总结一下,工作代码:

ma​​in.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();
    

Counter.h:

#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

Counter.cpp:

#include "Counter.h"

谢谢你,你太棒了!

【讨论】:

不客气。进一步的建议说明:如果您使用 Qt5,请养成使用新连接语法的习惯,因为它是类型安全的并在编译时检查:QObject::connect(&amp;button1, &amp;QPushButton::clicked, &amp;counter1, &amp;Counter::slot_incCounter);

以上是关于看起来如此 main.cpp:(.text.startup+0xd6): undefined reference to `vtable for Counter' 的错误?的主要内容,如果未能解决你的问题,请参考以下文章

从不同的 cpp 调用回调函数会导致 bad_function_call

struck(结构化SVM用于视觉跟踪)--源代码详解--main.cpp

struck(结构化SVM用于视觉跟踪)--源代码详解--main.cpp

用于构建 main.c 和 main.cpp 的单个 Makefile

main.cpp 和 mainwindow.cpp 之间的交互

将 boost 与自己的标头和源代码链接