我试图std::unique_ptr通过信号/插槽传递智能指针,但由于已删除的复制构造函数 ( unique_ptr(const unique_ptr&) = delete;) 而出现错误。那么是否可以std::unique_ptr在信号/表中使用智能指针?UDP:不!
相关问题:如何在线程之间传递大型容器?
重新制作了指针下的类std::shared_ptr<Data>。使用@yrHeTaTeJlb备注,我调用:Q_DECLARE_METATYPE(std::shared_ptr<Data>);和qRegisterMetaType<std::shared_ptr<Data>>("shared_ptr<Data>");。一切正常。
qDebug() 的输出:
Data();
finish
~Data();
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMap>
#include <memory>
class Data {
QMap<int, QString> _m; // большие
std::array<QString, 1024*1024> _a;
public:
Data() { qDebug() << "Data();"; }
~Data() { qDebug() << "~Data();"; }
void initData();
};
Q_DECLARE_METATYPE(std::shared_ptr<Data>);
class Worker : public QObject {
Q_OBJECT
std::shared_ptr<Data> _d;
public:
Worker() : QObject(), _d(std::make_shared<Data>()) { }
signals:
void finished(std::shared_ptr<Data> d);
public slots:
void process() { _d->initData(); emit finished(_d); }
};
class Controller : public QObject {
Q_OBJECT
std::shared_ptr<Data> _d;
public:
Controller(QObject *parent = nullptr) : QObject(parent) { }
void start();
signals:
void finished(std::shared_ptr<Data> d);
};
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
Controller _c;
std::shared_ptr<Data> _d;
};
#endif // MAINWINDOW_H
主窗口.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStandardItemModel>
#include <QThread>
void Data::initData() { /*some init code*/ }
void Controller::start() {
QThread *thr = new QThread;
Worker *w = new Worker;
w->moveToThread(thr);
connect(thr, &QThread::started, w, &Worker::process);
connect(w, &Worker::finished, this, &Controller::finished);
connect(w, &Worker::finished, thr, &QThread::quit);
connect(w, &Worker::finished, w, &Worker::deleteLater);
connect(thr, &QThread::finished, thr, &QThread::deleteLater);
thr->start();
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
qRegisterMetaType<std::shared_ptr<Data>>("shared_ptr<Data>");
ui->setupUi(this);
connect(&_c, &Controller::finished, this, [this] (std::shared_ptr<Data> d) { qDebug() << "finish"; _d = d; });
_c.start();
}
MainWindow::~MainWindow() { delete ui; }
默认情况下
connect,它将使用Qt::AutoConnection.如果信号在线程之间传递
Qt::AutoConnection==Qt::QueuedConnection为了传递 c 对象,
Qt::QueuedConnection它们的类型必须用QMetaType::qRegisterMetaType.为此,必须首先使用 声明类型
Q_DECLARE_METATYPE。Q_DECLARE_METATYPE要求类有一个复制构造函数,而std::unique_ptr没有。因此,
std::unique_ptr将信号从流传输到流是行不通的。