Qtが新しく、QThreadをコンソールアプリケーションで使用しようとしています。Qt:QThreadコピーのサブクラスで、コンパイラによってコンストラクタが削除されます
環境: Qt Creator 3.6.1; Qt5.6.0(MSVC2013 32ビット)に基づいています。 2016年3月14日に建設する。リビジョンd502727b2c私が何をしたか
は次のとおりです。
- はSTDコンテナベクトルを作成し、すべてのスレッドを開始するのstd :: for_eachを使用して、いくつかのスレッド
- を初期化
- QThreadクラスを継承する派生クラスQtThreadを作成します。ここで
はCLAでは、私の質問
まずありSS QtThread私はそうでないコピーコンストラクタ関数を実装する必要があり、私はコンパイルエラー
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
を持つことになり、私はここにコピーコンストラクタを実装する必要があります理由は、私が思うに、基底クラスQThreadはデストラクタを持ってい〜QThread()。したがって、コンパイラはcopy ctrをマークし、ctrをdeleteとして移動します。派生クラスは、基本クラスからコピー/移動ctrを継承しません。
これに関する3つの問題。
main関数では、emplace_back()を使用します。コンパイラはコピーコンストラクタを代わりに使用しているようです。なぜでしょうか?(std :: threadは移動のみで、コピーできないので、QThreadをコピーするのがちょっと奇妙です。私が実装コピーコンストラクタが良くない理由
QtThread(const QtThread &in_thread) = default; // not working, still having compile error C2280
私はそれだけで別のスレッドやコピーの名前を作成し、コンパイラは私のためにコピーCTRを生成できるようにするキーワードのデフォルトを使用することはできません)
を実現していませんスレッドの、私には良くないようですが、私はより良い解決策を見つけることができません。助言がありますか?
基本クラスQThreadには、仮想デストラクタはありません。それは私には珍しいようです。つまり、派生クラスは暗黙のうちに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();
}
おかげで投稿と私を助ける:)
[編集1]
メイン関数から実験コードを削除しました。
hydeとcod_fodderさんのおかげでコメントがありました。
私が思っている別の詳細なことがあります。コンパイラは、QtThreadのコピーコンストラクタをオーバーロードする必要があります(そうでなければ、コンパイラはエラーCC2280をスローします)。しかし、私が主な機能でしようとしているのは、オブジェクトをコンテナに移動することです。私は移動操作が失敗したときに、オブジェクトがコピーされることを知っています。この場合、Q_Objectはコピーされませんが、QtThreadオブジェクトを移動できない原因は何ですか?ブログwoboq.com/blog/qthread-you-were-not-doing-so-wrong.htmlで
QObjectサブクラスはコピーできません。また、QThreadはスレッドではなく、スレッドコントローラであることに注意してください。それをサブクラス化するだけで、スレッドの制御方法を変更したいのですが、QThread自体が制御するスレッドには存在しないことに注意してください。これはQtの非常に重要なディテールです。理解できない場合は、QThreadをサブクラス化しないでください。 – hyde
+1にハイデ、私はさらに詳しく説明します。あなたがしようとしていることは、QThreadを継承することなく、非常に簡単です。あなたがする必要があるのは、オブジェクトを作成し、QThreadを使って新しいスレッドを起動し、そのオブジェクトをそこに移動することです。ここでは今日の回答のリンクがあります(これは他にもたくさんあります)完了です:http://stackoverflow.com/questions/36201769/threads-event-loop-in-the-qt-application/36208479#36208479 –
ハイデ、ご意見ありがとうございます。ここで、以前のQtコア開発者の1人であるOlivier GoffartのQThreadのサブクラスについての記事を見つけました:http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html基本的に私はquesitonでイベントループを使用していません。だから私はここでQThreadを継承するべきです。 – r0ng