Qt的链接器错误:“未定义参考V表” [重复]Qt的链接器错误:“未定义参考V表” [重复](Qt

2019-05-09 08:56发布

这个问题已经在这里有一个答案:

  • 未定义引用的vtable。 尝试编译Qt工程 16个回答

这是我的头:

#ifndef BARELYSOCKET_H
#define BARELYSOCKET_H

#include <QObject>
//! The First Draw of the BarelySocket!

class BarelySocket: public QObject
{
    Q_OBJECT

public:
    BarelySocket();
public slots:
    void sendMessage(Message aMessage);
signals:
    void reciveMessage(Message aMessage);

private:
    //   QVector<Message> reciveMessages;
};

#endif // BARELYSOCKET_H

这是我的课:

#include <QTGui>
#include <QObject>
#include "type.h"
#include "client.h"
#include "server.h"

#include "barelysocket.h"

BarelySocket::BarelySocket()
{
    //this->reciveMessages.clear();
    qDebug("BarelySocket::BarelySocket()");
}

void BarelySocket::sendMessage(Message aMessage)
{
}

void BarelySocket::reciveMessage(Message aMessage)
{
}

我得到一个链接错误:

undefined reference to 'vtable for BarelySocket'
  • 这意味着我没有实现的虚拟方法。 但也有在我的课没有虚方法。
  • 我注释掉认为这是事业的载体,但错误没有消失。
  • Message是一个复杂的struct ,但即使使用int而不是没有解决的事情。

Answer 1:

任何时候你添加一个新的调用Q_OBJECT宏,你需要再次运行qmake的。 你指的是该虚函数表问题直接相关。

只要运行qmake的,你应该是好去假设有在你的代码中没有其他问题。



Answer 2:

我已经看到了很多办法来解决问题,但对于为什么会发生无法解释,所以这里去。

当编译器看到与虚拟功能(直接声明或继承)的一类,它必须产生用于该类的虚函数表。 由于类是在报头通常定义(并且因此出现在多个翻译单位),问题是在哪里放置虚表。

在一般情况下,这个问题可以通过在将类中定义的每个TU生成V表来解决,然后让接头消除重复。 由于类定义必须是由ODR每次出现一样的,这是安全的。 然而,它也减慢编译,腌目标文件,并要求连接器做更多的工作。

作为一种优化,因此,编译器会,如果可能的话,选择一个特定的TU把虚函数表中,在常见的C ++ ABI,这恩是一个在类的主要功能是实施了,其中关键的功能是即在类声明的,但不是限定的第一虚拟成员函数。

在Qt类的情况下,他们通常先从Q_OBJECT宏,这个宏包含的声明

virtual const QMetaObject *metaObject() const;

其中,因为它是在该宏所述第一虚拟功能,通常将类的第一虚拟功能,因此,其关键的功能。 因此,编译器不会发出大多数TU的虚函数表,只实现了一个metaObject 。 而这一功能的实现是通过自动写入moc当它处理的头。 因此,你需要有moc过程你的头,生成一个新的.cpp文件,然后在您编辑.cpp文件。

所以,当你有一个新的头定义了QObject派生类,你需要重新运行qmake ,以便更新您的makefile文件运行moc的新报头和编译生成的.cpp文件。



Answer 3:

我就遇到了这个错误我创建之后,我已创建来测试一些小“的main.cpp”文件内部一点儿类。

把玩了一小时左右后,我终于感动了该类出来的main.cpp,并成为一个独立的HPP文件,更新的.pro(项目)文件和项目,然后建立完美的罚款。 这可能不是一直在这里的问题,但我想这将是反正有用的信息。



Answer 4:

从以往的经验:常常一QMAKE &&使清洁&&化妆帮助。 我个人认为,有时变化发现/缓存效果/不管-I-鸵鸟政策知道XXXXX。 我不能说为什么,但它是我做的第一件事,当我遇到这样那样的错误。

顺便说一句。 有在> recive <错字

你忘了打电话给在构造函数QObject的构造函数(在初始化列表中)。 (它不解决,虽然错误)



Answer 5:

对于我来说,我从构建日志注意到,交通部才不叫。 干净的一切都没有帮助。 所以我删除.pro.user,重启IDE和它的伎俩。



Answer 6:

信号必须没有实现(这西港岛线由Qt的生成)。 取出reciveMessage从.cpp文件的实施。 这可能会解决你的问题。

我见过的其他事情:由于BarelySocket从QObject的类继承,它必须有一个虚析构函数,以避免破坏过程中的问题。 这必须从一个其他类继承所有的类来完成。



Answer 7:

当你派生自QObject类(或使用Q_OBJECT宏),不要忘了具体界定,并同时创建构造函数和析构函数的类。 这是不够的,使用编译器的默认构造函数/析构函数。 /对清洁的建议运行的qmake(和清除出你的moc_文件)仍然适用。 这个固定我类似的问题。



Answer 8:

我挣扎与此错误小时。 通过把在.cpp和.h文件中的一个单独的文件夹来解决它(!)。 然后在pro文件添加的文件夹:INCLUDEPATH + = $$ {_ PRO_FILE_PWD _} /../ MyClasses / CMyClassWidget

然后添加的.cpp和.h文件。 工程最后。



Answer 9:

我发现了另外一个原因,你可能会看到这一点-因为qmake解析通过你的类文件,如果你在一个非标准的方式,你可能会得到这个错误修改它们。 在我来说,我不得不从QDialog的继承一个自定义对话框,但我只想要一个编译和构建的Linux,而不是Windows或OSX时运行。 我#ifdef __linux__类出来所以没有编译,但即使Linux的__linux__定义它摆脱qmake



文章来源: Qt Linker Error: “undefined reference to vtable” [duplicate]