2016-03-24 6 views
1

Qtが新しく、QThreadをコンソールアプリケーションで使用しようとしています。Qt:QThreadコピーのサブクラスで、コンパイラによってコンストラクタが削除されます

環境: Qt Creator 3.6.1; Qt5.6.0(MSVC2013 32ビット)に基づいています。 2016年3月14日に建設する。リビジョンd502727b2c私が何をしたか

は次のとおりです。

  1. はSTDコンテナベクトルを作成し、すべてのスレッドを開始するのstd :: for_eachを使用して、いくつかのスレッド
  2. を初期化
  3. 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で

+9

QObjectサブクラスはコピーできません。また、QThreadはスレッドではなく、スレッドコントローラであることに注意してください。それをサブクラス化するだけで、スレッドの制御方法を変更したいのですが、QThread自体が制御するスレッドには存在しないことに注意してください。これはQtの非常に重要なディテールです。理解できない場合は、QThreadをサブクラス化しないでください。 – hyde

+0

+1にハイデ、私はさらに詳しく説明します。あなたがしようとしていることは、QThreadを継承することなく、非常に簡単です。あなたがする必要があるのは、オブジェクトを作成し、QThreadを使って新しいスレッドを起動し、そのオブジェクトをそこに移動することです。ここでは今日の回答のリンクがあります(これは他にもたくさんあります)完了です:http://stackoverflow.com/questions/36201769/threads-event-loop-in-the-qt-application/36208479#36208479 –

+0

ハイデ、ご意見ありがとうございます。ここで、以前のQtコア開発者の1人であるOlivier GoffartのQThreadのサブクラスについての記事を見つけました:http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html基本的に私はquesitonでイベントループを使用していません。だから私はここでQThreadを継承するべきです。 – r0ng

答えて

0

おかげで、それはイベントループが必要なとき、私たちは労働者/コントローラパターンを使用することができることを述べてそうでなければQThreadを継承するのは良いです。

関連する問題