オーバーロードされた関数 'operator'に 'スレッド'コードを配置すると、デストラクタが最初に呼び出されるように見えます。C++ 11スレッディング:オブジェクトがスレッドに置かれたときにデストラクターが呼び出される理由
これをデバッガで実行すると、文字通りスレッドの最初のステップはdestrを呼び出すことです。
だから、問題は、バットからすぐにdestrを呼び出さずにスレッドにオブジェクトを配置する方法です。
スレッドにオブジェクトを配置する4つの方法を示すプログラムです。それらのすべてはオブジェクトが使用される前にdestrを呼び出します(第4の方法はそれを2回呼び出します)。
注:アプローチ番号3を使用すると、operator()がオーバーロードされた関数でなくても実行されます。
#include <iostream>
#include <thread>
#include <unistd.h>
class MyClass {
private: int m_id;
public:
//constr
MyClass(int id) { m_id=id; std::cout << "constr_" << m_id << "\n";}
//destr
~MyClass() { std::cout << "destr_" << m_id << "\n"; }
//operator() override for thread
void operator()() {
while(true) {
std::cout << m_id << "\n";
sleep(1);
}
}
};
int main(int argc, char **argv) {
MyClass m1(1);
MyClass m2(2);
MyClass m3(3);
std::thread thread1 { m1 };
std::thread thread2(m2);
std::thread thread3(&MyClass::operator(), m3);
std::thread thread4{ MyClass(4) };
thread1.join();
return 0;
}
値でMyClassのコピーを渡す代わりに、スレッドへのMyClassのインスタンスにスマートポインタ(例:shared_ptr)を渡すことができます。これは、あなたの例のように、main()内のスマートポインタのコピーがスレッドの作成直後にスコープから外れている限り、問題ありません。 – bazza