私の目的は、std::thread
オブジェクトをデータメンバーとして保持し、必要に応じて初期化することです。std::thread
クラスのコピーコンストラクターが削除されているため、これを行うことができません(以下のコードのように)。それを行う他の方法はありますか?
class MyClass
{
public:
MyClass():DiskJobThread(){};
~MyClass();
void DoDiskJobThread();
private:
int CopyThread(const std::wstring & Source, const std::wstring & Target);
int MoveThread(const std::wstring & Source, const std::wstring & Target);
std::thread DiskJobThread;
};
MyClass::~MyClass()
{
DiskJobThread.join();
}
void MyClass::DoDiskJobThread()
{
std::wstring Source = GetSource();
std::wstring Target = GetTarget();
int m_OperationType = GetOperationType();
if (m_OperationType == OPERATION_COPY)
{
DiskJobThread = std::thread(&MyClass::CopyThread, *this, Source, Target);
}
else if (m_OperationType == OPERATION_MOVE)
{
DiskJobThread = std::thread(&MyClass::MoveThread, *this, Source, Target);
}
}
問題は別のものです。メンバー関数が期待するMyClass
へのポインターではなく、MyClass
のインスタンスをスレッドに渡しています。 DoDiskJobThread()
を次のように変更するだけです(this
を逆参照しないでください):
void MyClass::DoDiskJobThread()
{
std::wstring Source = GetSource();
std::wstring Target = GetTarget();
int m_OperationType = GetOperationType();
if (m_OperationType == OPERATION_COPY)
{
DiskJobThread = std::thread(&MyClass::CopyThread, this, Source, Target);
}
else if (m_OperationType == OPERATION_MOVE)
{
DiskJobThread = std::thread(&MyClass::MoveThread, this, Source, Target);
}
}
*this
がMyClass
をスレッド関数にコピーしようとしたためにエラーが発生し、クラスのコピーctorが削除されました(std::thread
のコピーctorが削除されたため)。ただし、メンバー関数CopyThread
およびMoveThread
には、とにかく最初の(非表示の)引数としてポインターが必要です。
ポインタでラップするのはどうですか?
std::unique_ptr<std::thread> thread_ptr;
// Look into std::make_unique if possible
thread_ptr = std::unique_ptr<std::thread>(new std::thread(...));
編集:はい、他の人がそれについて言及していて、ここに追加する必要性を感じませんでしたが、より多くの反対意見の積み重ねを避けるために、私はそれを言います:あなたは*this
とthis
ではなく、それによってクラスのインスタンスをコピーします。 (コピーできないため、問題が発生します。this
を渡すと、問題が発生するはずです。)
作成後にスレッドオブジェクトを初期化することはできません。定義上、初期化はオブジェクトの作成時に発生します。ただし、swap
を使用して、スレッドオブジェクトを別のオブジェクトに移動できます。
std::thread thr1; // no thread of execution
std::thread thr2(my_function_object); // creates thread of execution
thr1.swap(thr2); // thr1 is now running the thread created as thr2
// and thr2 has no thread of execution