对于...的vtable未定义引用

5

我正在尝试编写一个Http代理,其基本工作原理类似于indianwebproxy

所以我启动了qtcreator,但我的其中一个类无法通过编译,出现了臭名昭著的错误:undefined reference to vtable for HttpProxyThreadBrowser。我想不通为什么会这样。我在Stackoverflow上阅读了类似的问题,并且显然问题出在未定义的虚拟方法上,这些方法不是纯虚函数,但我没有声明任何虚拟函数。这是我的类:

class HttpProxyThreadBrowser : public QThread
{
public:
    HttpProxyThreadBrowser(QTcpSocket outgoingSocket,QTcpSocket  browserSocket,QObject *parent = 0);
    ~HttpProxyThreadBrowser(){};
    void run();

private:
    QTcpSocket outgoingSocket;
    QTcpSocket browserSocket;

};

我在pastebin中定义了这个类,以免让你感到无聊。不幸的是,我找不出为什么虚函数表未定义。请协助解决。

httpproxythreadbrowser.cpp:5: undefined reference to `vtable for HttpProxyThreadBrowser
collect2: ld returned 1 exit status

根据文档,run是一个受保护的成员,而不是公共的。虽然我怀疑这不会是你错误的源头。 - obmarg
@obmarg:是的,因为run是虚拟的,而他从未定义它。 - PlasmaHH
嗯...在我的电脑上编译正常。使用的是MinGw的4.7.4和4.8.0版本。你用的是哪个操作系统/Qt版本? - Chris Browet
1
对于通过谷歌搜索进入此处的任何人:我们之所以出现这个错误,是因为.pro文件中有额外的空格。 - AndrewS
2
@stativ的回答在这种情况下并不正确,但在使用Qt时,这是一种非常常见的导致此错误消息的原因。如果您添加了一个新的QObject派生类,但忘记将其添加到HEADERS变量中(或以其他方式运行moc并链接生成的对象),那么这正是所看到的错误消息。对于许多遇到这个问题的人来说,这将是问题的根本原因... - evadeflow
显示剩余2条评论
4个回答

10

析构函数是隐式虚函数,因为基类有虚析构函数。

GNU编译器会将vtable与第一个非内联虚方法("关键方法")一起发出。由于您的析构函数在类内定义,它隐式地是虚函数,并且没有其他虚拟方法,因此您没有关键方法。

不存在仅具有虚拟内联方法的具体类的用例,因为它们只能内联到派生类中。

我建议您将析构函数的定义移到实现文件中。

我不确定您是否需要在这里使用moc,或者如果QThread衍生类不使用它(如果我没记错,您仅需要用它来进行Qt的转换操作和信号/槽)。


7

4

您不能复制QTcpSocket,如果您尝试通过复制而不是通过地址传递它们,可能会导致其他难以理解的错误。

    HttpProxyThreadBrowser(QTcpSocket * outgoingSocket,QTcpSocket * browserSocket,QObject *parent = 0);

private:
    QTcpSocket* outgoingSocket;
    QTcpSocket* browserSocket;

当您更改头文件时,重新编译整个项目可能有帮助,因为qmake生成的Makefile有时无法注意到这些更改。


1
另一种解决方案是通过引用传递QTcpSocket,即HttpProxyThreadBrowser(QTcpSocket&outgoingSocket,QTcpSocket&browserSocket,QObject * parent = 0); - Chris Browet
非常感谢大家。但这让我想知道为什么我无法复制QTcpSockets,但这是另一天的故事了。 - Dr Deo

3

这通常是由于没有链接automoc生成的文件引起的。

首先,您需要在定义使用Q_OBJECT的类的头文件上运行automoc,在您的情况下是“httpproxythreadbrowser.h”。这将生成一个“*.moc”文件。

现在有两种常见的方法可以继续。要么您可以在类定义的.cpp文件末尾#include .moc文件,要么您可以将其作为另一个源文件传递给编译器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接