Qt:在QThread副本的子class中,构造函数被编译器删除
Qt: in a sub-class of QThread copy, the constructor is deleted by compiler
我是 Qt 的新手,正在尝试在控制台应用程序中使用 QThread。
环境:
Qt 创作者 3.6.1;基于Qt5.6.0(MSVC2013 32bit);建立于 2016 年 3 月 14 日;修订版 d502727b2c
我做的是:
- 创建派生class QtThread 继承QThread class
- 创建一个标准容器向量并初始化几个线程
- 使用std::for_each启动所有线程
这是我的问题
首先,在classQtThread中必须实现拷贝构造函数,否则会编译出错
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0:657: error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
我认为我必须在这里实现复制构造函数的原因是基础 class QThread 具有析构函数 ~QThread()。所以编译器会将copy ctr和move ctr标记为delete。派生的 class 不从基础 class.
继承 copy/move ctr
三个问题。
在主函数中,我使用了emplace_back()。编译器似乎使用了复制构造函数而不是 move.Why~(std::thread 只是移动,无法复制,所以 QThread 可以复制对我来说有点奇怪,或者我做错了什么但我没有意识到)
我不能使用关键字 default 让编译器为我生成复制点击率,为什么
QtThread(const QtThread &in_thread) = default; // not working, still having compile error C2280
我实现的复制构造函数不好,只是创建另一个线程并复制线程的名称,我觉得不太好,但我找不到更好的解决方案。有什么建议吗?
基础class QThread 没有虚拟析构函数。这对我来说似乎很不寻常。这意味着 derived class 不能隐式调用 QThread 的析构函数。或者我根本不应该继承 QThread?
这是我声明 QtThread 的代码:
#pragma once
#include <QtCore>
#include <QDebug>
#define qtout qDebug()
class QtThread : public QThread
class QtThread : public QThread
{
Q_OBJECT
public:
QtThread():QThread(nullptr){}
explicit QtThread(const QString &in_name);
// This copy constructor create a different thread with same name, bad
QtThread(const QtThread &in_thread) : QThread() { m_name = in_thread.m_name;} // have to implement copy constructor otherwise, the code will have error: C2280 compile error
//error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
//QtThread(const QtThread &in_thread) = default;
void run();
QString m_name;
};
cpp文件
#include "qtthread.h"
QtThread::QtThread(const QString &in_name)
: QThread()
, m_name(in_name)
{}
void QtThread::run()
{
qtout << "QtThread" << m_name << "start to run";
for(int i = 0; i<1000; i++)
qtout << m_name << ": " << i;
}
这里是主要功能
#include <QCoreApplication>
#include "qtthread.h"
#include <vector>
#include <algorithm>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::vector<QtThread> ts;
ts.emplace_back(QtThread("Tx"));
ts.emplace_back(QtThread("T5"));
ts.emplace_back(QtThread("T6"));
std::for_each(ts.begin(), ts.end(), [](QtThread &t){t.start();});
return a.exec();
}
感谢您花时间阅读冗长的 post 并帮助我 :)
[编辑 1]
从主函数中删除了一些实验性代码。
感谢 hyde,cod_fodder 发表评论。
还有一个细节我想知道。编译器要求我为 QtThread 重载复制构造函数(否则编译器会抛出错误 CC2280)。但是我在 main 函数中尝试做的是将对象移动到容器中。我知道当移动操作失败时,对象将被复制。在这种情况下,Q_Object不应该被复制,但是QtThread对象无法移动的原因是什么?
谢谢
博客woboq.com/blog/qthread-you-were-not-doing-so-wrong.html中说,当需要事件循环时,可以使用worker/controller模式,否则继承QThread就好了。
我是 Qt 的新手,正在尝试在控制台应用程序中使用 QThread。
环境: Qt 创作者 3.6.1;基于Qt5.6.0(MSVC2013 32bit);建立于 2016 年 3 月 14 日;修订版 d502727b2c
我做的是:
- 创建派生class QtThread 继承QThread class
- 创建一个标准容器向量并初始化几个线程
- 使用std::for_each启动所有线程
这是我的问题
首先,在classQtThread中必须实现拷贝构造函数,否则会编译出错
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xmemory0:657: error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
我认为我必须在这里实现复制构造函数的原因是基础 class QThread 具有析构函数 ~QThread()。所以编译器会将copy ctr和move ctr标记为delete。派生的 class 不从基础 class.
继承 copy/move ctr三个问题。
在主函数中,我使用了emplace_back()。编译器似乎使用了复制构造函数而不是 move.Why~(std::thread 只是移动,无法复制,所以 QThread 可以复制对我来说有点奇怪,或者我做错了什么但我没有意识到)
我不能使用关键字 default 让编译器为我生成复制点击率,为什么
QtThread(const QtThread &in_thread) = default; // not working, still having compile error C2280
我实现的复制构造函数不好,只是创建另一个线程并复制线程的名称,我觉得不太好,但我找不到更好的解决方案。有什么建议吗?
基础class QThread 没有虚拟析构函数。这对我来说似乎很不寻常。这意味着 derived class 不能隐式调用 QThread 的析构函数。或者我根本不应该继承 QThread?
这是我声明 QtThread 的代码:
#pragma once
#include <QtCore>
#include <QDebug>
#define qtout qDebug()
class QtThread : public QThread
class QtThread : public QThread
{
Q_OBJECT
public:
QtThread():QThread(nullptr){}
explicit QtThread(const QString &in_name);
// This copy constructor create a different thread with same name, bad
QtThread(const QtThread &in_thread) : QThread() { m_name = in_thread.m_name;} // have to implement copy constructor otherwise, the code will have error: C2280 compile error
//error: C2280: 'QtThread::QtThread(const QtThread &)': attempting to reference a deleted function
//QtThread(const QtThread &in_thread) = default;
void run();
QString m_name;
};
cpp文件
#include "qtthread.h"
QtThread::QtThread(const QString &in_name)
: QThread()
, m_name(in_name)
{}
void QtThread::run()
{
qtout << "QtThread" << m_name << "start to run";
for(int i = 0; i<1000; i++)
qtout << m_name << ": " << i;
}
这里是主要功能
#include <QCoreApplication>
#include "qtthread.h"
#include <vector>
#include <algorithm>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::vector<QtThread> ts;
ts.emplace_back(QtThread("Tx"));
ts.emplace_back(QtThread("T5"));
ts.emplace_back(QtThread("T6"));
std::for_each(ts.begin(), ts.end(), [](QtThread &t){t.start();});
return a.exec();
}
感谢您花时间阅读冗长的 post 并帮助我 :)
[编辑 1]
从主函数中删除了一些实验性代码。
感谢 hyde,cod_fodder 发表评论。
还有一个细节我想知道。编译器要求我为 QtThread 重载复制构造函数(否则编译器会抛出错误 CC2280)。但是我在 main 函数中尝试做的是将对象移动到容器中。我知道当移动操作失败时,对象将被复制。在这种情况下,Q_Object不应该被复制,但是QtThread对象无法移动的原因是什么?
谢谢
博客woboq.com/blog/qthread-you-were-not-doing-so-wrong.html中说,当需要事件循环时,可以使用worker/controller模式,否则继承QThread就好了。