这个问题已经在这里有一个答案:
- 未定义引用的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
而不是没有解决的事情。
任何时候你添加一个新的调用Q_OBJECT宏,你需要再次运行qmake的。 你指的是该虚函数表问题直接相关。
只要运行qmake的,你应该是好去假设有在你的代码中没有其他问题。
我已经看到了很多办法来解决问题,但对于为什么会发生无法解释,所以这里去。
当编译器看到与虚拟功能(直接声明或继承)的一类,它必须产生用于该类的虚函数表。 由于类是在报头通常定义(并且因此出现在多个翻译单位),问题是在哪里放置虚表。
在一般情况下,这个问题可以通过在将类中定义的每个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文件。
我就遇到了这个错误我创建之后,我已创建来测试一些小“的main.cpp”文件内部一点儿类。
把玩了一小时左右后,我终于感动了该类出来的main.cpp,并成为一个独立的HPP文件,更新的.pro(项目)文件和项目,然后建立完美的罚款。 这可能不是一直在这里的问题,但我想这将是反正有用的信息。
从以往的经验:常常一QMAKE &&使清洁&&化妆帮助。 我个人认为,有时变化发现/缓存效果/不管-I-鸵鸟政策知道XXXXX。 我不能说为什么,但它是我做的第一件事,当我遇到这样那样的错误。
顺便说一句。 有在> recive <错字
你忘了打电话给在构造函数QObject的构造函数(在初始化列表中)。 (它不解决,虽然错误)
对于我来说,我从构建日志注意到,交通部才不叫。 干净的一切都没有帮助。 所以我删除.pro.user,重启IDE和它的伎俩。
信号必须没有实现(这西港岛线由Qt的生成)。 取出reciveMessage
从.cpp文件的实施。 这可能会解决你的问题。
我见过的其他事情:由于BarelySocket
从QObject的类继承,它必须有一个虚析构函数,以避免破坏过程中的问题。 这必须从一个其他类继承所有的类来完成。
当你派生自QObject类(或使用Q_OBJECT宏),不要忘了具体界定,并同时创建构造函数和析构函数的类。 这是不够的,使用编译器的默认构造函数/析构函数。 /对清洁的建议运行的qmake(和清除出你的moc_文件)仍然适用。 这个固定我类似的问题。
我挣扎与此错误小时。 通过把在.cpp和.h文件中的一个单独的文件夹来解决它(!)。 然后在pro文件添加的文件夹:INCLUDEPATH + = $$ {_ PRO_FILE_PWD _} /../ MyClasses / CMyClassWidget
然后添加的.cpp和.h文件。 工程最后。
我发现了另外一个原因,你可能会看到这一点-因为qmake
解析通过你的类文件,如果你在一个非标准的方式,你可能会得到这个错误修改它们。 在我来说,我不得不从QDialog的继承一个自定义对话框,但我只想要一个编译和构建的Linux,而不是Windows或OSX时运行。 我#ifdef __linux__
类出来所以没有编译,但即使Linux的__linux__
定义它摆脱qmake
。