对已定义的接口析构函数的未定义引用

Undefined reference to already defined interface destructor

本文关键字:未定义 引用 析构函数 接口 定义      更新时间:2023-10-16

我有一个接口QInterruptable如下:

#ifndef QINTERRUPTABLE_H
#define QINTERRUPTABLE_H
class QInterruptable {
public:
virtual void pause();
virtual void resume();
virtual void interrupt();
virtual ~QInterruptable(){
}
};
#endif // QINTERRUPTABLE_H

QInterruptable的一个示例用途是子类化QThreadWorkerObject 以获得其他功能。

QInterruptable在我的ThreadWorker头文件中使用

#ifndef THREADWORKER_H
#define THREADWORKER_H
#include <QObject>
#include <functional>
#include <QWaitCondition>
#include <QMutex>
#include "QInterruptable.h"
class ThreadWorker : public QObject, public QInterruptable
{
Q_OBJECT
private:
QMutex mutex;
QWaitCondition *waitCondition;
std::function<void ()> runnable;
bool shouldPause = false;
public:
explicit ThreadWorker(QObject *parent = nullptr);
ThreadWorker(std::function<void ()> func);
~ThreadWorker();
void setRunnable(const std::function<void ()> &value);
signals:
void started();
void progress(int value);
void finished();
void error();
public slots:
virtual void run();
virtual void cleanup();
// QInterruptable interface
public:
void pause()
{
shouldPause = true;
}
void resume()
{
shouldPause = false;
}
void interrupt()
{
}
QMutex& getMutex();
QWaitCondition *getWaitCondition() const;
void setWaitCondition(QWaitCondition *value);
bool getShouldPause() const;
#endif // THREADWORKER_H

编译时,我遇到了此错误:

debug/threadworker.o: In function `ZN14QInterruptableD2Ev':
C:UsersCybeXQtProjectsbuild-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug/../qMyAwesomeApp/3rd-party/QThreading/QThreading/QInterruptable.h:9: undefined reference to `vtable for QInterruptable'
debug/threadworker.o: In function `ZN14QInterruptableC2Ev':
C:UsersCybeXQtProjectsbuild-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug/../qMyAwesomeApp/3rd-party/QThreading/QThreading/QInterruptable.h:4: undefined reference to `vtable for QInterruptable'
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: *** [Makefile.Debug:195: debug/MyAwesomeApp.exe] Error 1
mingw32-make: *** [Makefile:38: debug] Error 2
mingw32-make[1]: Leaving directory 'C:/Users/CybeX/QtProjects/build-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug'
09:29:08: The process "F:QtQt5.13.1Toolsmingw730_32binmingw32-make.exe" exited with code 2.
Error while building/deploying project MyAwesomeApp (kit: Desktop Qt 5.13.1 MinGW 32-bit)
When executing step "Make"

我看过实现C++接口的解决方案和undefined references to destructors的解决方案。我发现这个,这个,这个特别提到了我的问题。

如您所见,我尝试使用

virtual ~QInterruptable(){
}

这会导致上述错误。

如果我使用这样的纯虚拟desctructor :

virtual ~QInterruptable() = 0;

然后我将问题传递给子类,即ThreadWorker出现以下错误:

debug/threadworker.o: In function `ZN12ThreadWorkerC2EP7QObject':
C:UsersCybeXQtProjectsbuild-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug/../qMyAwesomeApp/3rd-party/QThreading/QThreading/threadworker.cpp:28: undefined reference to `QInterruptable::~QInterruptable()'
debug/threadworker.o: In function `ZN12ThreadWorkerC2ESt8functionIFvvEE':
C:UsersCybeXQtProjectsbuild-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug/../qMyAwesomeApp/3rd-party/QThreading/QThreading/threadworker.cpp:33: undefined reference to `QInterruptable::~QInterruptable()'
debug/threadworker.o: In function `ZN12ThreadWorkerD2Ev':
C:UsersCybeXQtProjectsbuild-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug/../qMyAwesomeApp/3rd-party/QThreading/QThreading/threadworker.cpp:37: undefined reference to `QInterruptable::~QInterruptable()'
debug/threadworker.o: In function `ZN14QInterruptableC2Ev':
C:UsersCybeXQtProjectsbuild-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug/../qMyAwesomeApp/3rd-party/QThreading/QThreading/QInterruptable.h:4: undefined reference to `vtable for QInterruptable'
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: *** [Makefile.Debug:195: debug/MyAwesomeApp.exe] Error 1
mingw32-make: *** [Makefile:38: debug] Error 2
mingw32-make[1]: Leaving directory 'C:/Users/CybeX/QtProjects/build-MyAwesomeApp-Desktop_Qt_5_13_1_MinGW_32_bit-Debug'
09:33:51: The process "F:QtQt5.13.1Toolsmingw730_32binmingw32-make.exe" exited with code 2.
Error while building/deploying project MyAwesomeApp (kit: Desktop Qt 5.13.1 MinGW 32-bit)
When executing step "Make"

其中违规ThreadWorker.cpp行是:

[28] ThreadWorker::ThreadWorker(QObject *parent) : QObject(parent)
[29] {
[30]     waitCondition = new QWaitCondition;
[31] }
[32] 
[33] ThreadWorker::ThreadWorker(std::function<void ()> func): runnable(func) {
[34]     waitCondition = new QWaitCondition;
[35] }
[36] 
[37] ThreadWorker::~ThreadWorker()
[38] {
[39]     if(waitCondition != nullptr){
[40]         delete waitCondition;
[41]     }
[42] }

如何解决此对接口析构函数问题的未定义引用?

您有对基类的 vtable 的未定义引用,因为您没有为基类的所有虚拟(机器人非纯虚拟(方法提供定义,即:pauseresumeinterrupt。现在,如果您声明 3 个方法是纯虚拟的,则不需要对它们进行定义。或者,您可以将它们保留为非纯虚拟并编写一些默认定义。请注意,析构函数也是一个虚拟方法,也必须定义,但是您可以通过显式告诉编译器为您生成一个virtual ~QInterruptable() = default来简化它。GCC FAQ 中有一个关于它的条目。