在 qt C++ 信号和槽中使用已删除函数错误

Posted

技术标签:

【中文标题】在 qt C++ 信号和槽中使用已删除函数错误【英文标题】:Use of deleted function error in qt C++ signals and slots 【发布时间】:2017-11-12 04:44:24 【问题描述】:

任何人都可以帮助我,为什么即使我将参数作为指针引用 (*&) 传递,我也会收到这个已删除的函数错误?这是一个在 Qt 中使用多线程的简单项目,我只想尝试在父线程和子线程之间共享和修改对象。我是 Qt 新手,我在 Ubuntu Linux 14.04 上使用 Qt 5.9.2 和 GCC 4.9.4。

提前致谢。

===== Controller.hpp ===========
#pragma once

#include "data.hpp"

#include <QObject>
#include <QThread>

class Controller : public QObject

    Q_OBJECT
    QThread workerThread;
public:
    explicit Controller(QObject *parent = nullptr);
    ~Controller();

signals:
    void operate(Data*& data);

public slots:
    void handleResults(int idx);

private:
    Data _data;
;

===== Controller.cpp ===========
#include "controller.hpp"
#include "worker.hpp"

#include <QDebug>

Controller::Controller(QObject *parent) : QObject(parent)

    Worker *worker = new Worker;
    worker->moveToThread(&workerThread);
    connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
    connect(this, &Controller::operate, worker, &Worker::doWork);
    connect(worker, &Worker::resultReady, this, &Controller::handleResults);
    workerThread.start();

    emit operate(&_data);


Controller::~Controller()

    workerThread.quit();
    workerThread.wait();


void Controller::handleResults(int idx)

    qDebug() << _data.at(idx);


===== Worker.hpp ===========
#pragma once

#include "data.hpp"

#include <QObject>

class Worker : public QObject

    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);

signals:
    void resultReady(int idx);

public slots:
    void doWork(Data*& data);
;

===== Worker.cpp ===========
#include "worker.hpp"

Worker::Worker(QObject *parent) : QObject(parent)



void Worker::doWork(Data*& data)

    data->insertVal(10);
    emit resultReady(data->getSize());


===== Data.hpp ===========
#pragma once

#include <QObject>
#include <QVector>

class Data : public QObject

    Q_OBJECT
public:
    explicit Data(QObject *parent = nullptr);

    void insertVal(int i);
    int getSize() const  return _intVec.size(); 

private:
    QVector<int*> _intVec;
;

===== Data.cpp ===========
#include <QDebug>

#include "data.hpp"

Data::Data(QObject *parent) : QObject(parent)



void Data::insertVal(int i)

    _intVec << &i;
    qDebug() << "Data inserted: " << i;


===== main.cpp ===========
#include "controller.hpp"
#include "data.hpp"

#include <QCoreApplication>

int main(int argc, char *argv[])

    qRegisterMetaType<Data>("Data");

    QCoreApplication a(argc, argv);

    Controller con;
    return a.exec();

我收到以下错误:

/home/raze/Qt/5.9.2/gcc_64/include/QtCore/qmetatype.h:765: error: use of deleted function ‘Data::Data(const Data&)’
             return new (where) T(*static_cast<const T*>(t));

/home/raze/Qt/5.9.2/gcc_64/include/QtCore/qobject.h:454: error: ‘QObject::QObject(const QObject&)’ is private
     Q_DISABLE_COPY(QObject)
                    ^
                                                           ^
/home/raze/Documents/Qt_projects/PracThread/data.hpp:6: error: within this context
 class Data : public QObject
       ^

/home/raze/Documents/Qt_projects/PracThread/data.hpp:6: error: use of deleted function ‘QObject::QObject(const QObject&)’

【问题讨论】:

你应该通过指针传递 QObject , QObject Data 通过 Worker 和 Controller 类,你可以使用 QSharedPointer 一起传递它们并且 QObject 类是不可复制的,你不能通过值传递它 感谢您的回答。但是我没有正确理解您的建议,我将我的 Data 类作为 *& 传递,它不应该调用复制构造函数,并且我不想为我的 QObject 数据类型包含复制构造函数。能否请您详细说明一下,由于我是 C++ 和 Qt 的新手,因此示例代码行可能会更有帮助。 好的,我会提供样品等一下 【参考方案1】:

如果您将void operate(Data*&amp; data); 更改为void operate(Data* data); 在 Controller 类中并将 void doWork(Data*&amp; data); 更改为 void doWork(Data* data); 在 worker 类中,您的代码编译得很好但是从我的评论阅读 How Qt Signals and Slots Work 和 Effective Threading Using Qt 这篇文章看起来很适合所有 Qt/C++ 的新手。

编辑:

来自@altaf cmets:澄清一下,问题的根源是由我的main.cpp 文件中的qRegisterMetaType&lt;Data&gt;("Data"); 引起的。数据应该由指针通过信号和槽传递,所以它应该被注册为 qRegisterMetaType&lt;*Data&gt;("pData"); 所有信号和槽都应该将参数作为 Data* pData

【讨论】:

我刚刚更改了它,但得到了同样的错误。感谢您的链接,将阅读它。 我正在使用 gcc (Ubuntu 7.2.0-8ubuntu3) 7.2.0 作为编译器编译代码。你的编译器是什么,如果我可以重现你的问题,我会帮助你。希望能帮到你,谢谢。 Qt 5.9.2 和 GCC 版本 4.9.4 (Ubuntu 4.9.4-2ubuntu1~14.04.1) 64 位,我使用的是 Qt 社区版 @Altaf 如果您愿意,我可以将我创建的整个示例项目发送给您,它可以以任何方式编译。 拜托,我的电子邮件:altaf.mahmud@gmail 或者如果您愿意,也可以在这里发布,其他人也可能会得到帮助。谢谢。

以上是关于在 qt C++ 信号和槽中使用已删除函数错误的主要内容,如果未能解决你的问题,请参考以下文章

被 qt 4 信号和槽中的 clicked() 和 clicked(bool) 混淆

C++框架_之Qt的信号和槽的详解

C++ GUI Qt的建立连接,信号和槽

Qt C++ 信号和槽没有触发

Qt 信号槽传递自定义结构体

Qt 信号槽