C++ Qt链接器错误:";未定义对vtable的引用;

C++ Qt链接器错误:";未定义对vtable的引用;,c++,qt,linker-errors,vtable,qobject,C++,Qt,Linker Errors,Vtable,Qobject,这是我的标题: \ifndef BARELYSOCKET\u H #定义BARELYSOCKET_H #包括 //! BarelySocket的第一次抽签! BarelySocket类:公共QObject { Q_对象 公众: BarelySocket(); 公众时段: 无效发送消息(消息A消息); 信号: 无效接收消息(消息A消息); 私人: //QVector接收消息; }; #endif//BARELYSOCKET_H 这是我的班级: #包括 #包括 #包括“h型” #包括“clien

这是我的标题:

\ifndef BARELYSOCKET\u H
#定义BARELYSOCKET_H
#包括
//! BarelySocket的第一次抽签!
BarelySocket类:公共QObject
{
Q_对象
公众:
BarelySocket();
公众时段:
无效发送消息(消息A消息);
信号:
无效接收消息(消息A消息);
私人:
//QVector接收消息;
};
#endif//BARELYSOCKET_H
这是我的班级:

#包括
#包括
#包括“h型”
#包括“client.h”
#包括“server.h”
#包括“barelysocket.h”
BarelySocket::BarelySocket()
{
//此->receivemessages.clear();
qDebug(“BarelySocket::BarelySocket()”;
}
void BarelySocket::sendMessage(Message aMessage)
{
}
void BarelySocket::reciveMessage(Message aMessage)
{
}
我收到一个链接器错误:

对“用于BarelySocket的vtable”的未定义引用
  • 这意味着我有一个虚拟方法没有实现。但是那里 在我的类中没有虚拟方法
  • 我注释掉了向量,认为这是原因,但是 错误并没有消失
  • 消息
    是一个复杂的
    结构
    ,但即使使用
    int
    也不例外 不要修理东西

从经验来看:qmake&make clean&make通常有帮助。 我个人认为有时变更发现/缓存效果/我不知道的任何xxxxx。我不知道为什么,但这是我遇到这种错误时做的第一件事


顺便说一句,根据经验,>recive有一个拼写错误:通常是qmake&&makeclean&&makehelp。 我个人认为有时变更发现/缓存效果/我不知道的任何xxxxx。我不知道为什么,但这是我遇到这种错误时做的第一件事


顺便说一句,在>接收信号处有一个输入错误,不能有一个实现(这将由Qt生成)。从.cpp文件中删除接收消息的实现。这可能会解决你的问题


我还看到了另一件事:由于
BarelySocket
类继承自QObject,因此它必须有一个虚拟析构函数,以避免在销毁过程中出现问题。必须对从其他类继承的所有类执行此操作。

信号不得有实现(这将由Qt生成)。从.cpp文件中删除接收消息的实现。这可能会解决你的问题


我还看到了另一件事:由于
BarelySocket
类继承自QObject,因此它必须有一个虚拟析构函数,以避免在销毁过程中出现问题。必须对从其他类继承的所有类执行此操作。

我在为测试某些内容而创建的小“main.cpp”文件中创建了一个小类后,遇到了此错误


经过一个小时左右的思考,我最终将该类从main.cpp迁移到一个独立的hpp文件中,更新了.pro(project)文件,然后该项目构建得非常好。这可能不是这里的问题,但我认为它无论如何都是有用的信息。

在我创建的一个小“main.cpp”文件中创建了一个小类来测试某些东西后,我遇到了这个错误


经过一个小时左右的思考,我最终将该类从main.cpp迁移到一个独立的hpp文件中,更新了.pro(project)文件,然后该项目构建得非常好。这可能不是这里的问题,但我认为它无论如何都是有用的信息。

任何时候向Q_对象宏添加新调用时,都需要再次运行qmake。您所指的vtables问题与此直接相关


只要运行qmake,假设代码中没有其他问题,就可以继续运行了。

任何时候向Q_对象宏添加新调用时,都需要再次运行qmake。您所指的vtables问题与此直接相关


只要运行qmake,假设代码中没有其他问题,您就可以开始了。

当您从QOBject派生类(并使用Q_OBJECT宏)时,不要忘记明确定义和创建构造函数和析构函数类。仅使用编译器默认构造函数/析构函数是不够的。关于清理/运行qmake(以及清除moc文件)的建议仍然适用。
这解决了我的类似问题。

当您从QOBject派生类(并使用Q_OBJECT宏)时,不要忘记明确定义和创建构造函数和析构函数类。仅使用编译器默认构造函数/析构函数是不够的。关于清理/运行qmake(以及清除moc文件)的建议仍然适用。
这解决了我类似的问题。

对于我来说,我从构建日志中注意到没有调用moc。把所有的东西都清理干净也没用。所以我删除了.pro.user,重新启动了IDE,它成功了。

对于我来说,我从构建日志中注意到没有调用moc。把所有的东西都清理干净也没用。因此,我删除了.pro.user,重新启动了IDE,它成功了。

我已经看到了很多解决问题的方法,但没有解释为什么会发生这种情况,下面就是

当编译器看到具有虚拟函数(直接声明或继承)的类时,它必须为该类生成vtable。由于类通常是在标题中定义的(因此出现在多个翻译单元中),所以问题是将vtable放在何处

通常,可以通过在定义类的每个TU*中生成vtable,然后让链接器消除重复项来解决问题。由于ODR**要求每次出现时类定义都相同,因此这是安全的。但是,它也会减慢编译速度,使对象文件膨胀,并需要链接器做更多的工作

因此,作为一种优化,编译器将在可能的情况下选择一个特定的TU来放置vtable。在普通C++中,这个TU是一个在其中实现键函数的键,其中键函数是第一个虚拟m。
virtual const QMetaObject *metaObject() const;