Anda kehilangan instruksi pembuatan salinan dan memindahkan konstruksi. Modifikasi sederhana untuk program Anda akan memberikan bukti di mana konstruksi berlangsung.
Salin Pembuat
#include <iostream>
#include <thread>
#include <functional>
using namespace std;
class tFunc{
int x;
public:
tFunc(){
cout<<"Constructed : "<<this<<endl;
x = 1;
}
tFunc(tFunc const& obj) : x(obj.x)
{
cout<<"Copy constructed : "<<this<< " (source=" << &obj << ')' << endl;
}
~tFunc(){
cout<<"Destroyed : "<<this<<endl;
}
void operator()(){
x += 10;
cout<<"Thread running at : "<<x<<endl;
}
int getX() const { return x; }
};
int main()
{
tFunc t;
thread t1{t};
if(t1.joinable())
{
cout<<"Thread is joining..."<<endl;
t1.join();
}
cout<<"x : "<<t.getX()<<endl;
return 0;
}
Output (alamat bervariasi)
Constructed : 0x104055020
Copy constructed : 0x104055160 (source=0x104055020)
Copy constructed : 0x602000008a38 (source=0x104055160)
Destroyed : 0x104055160
Thread running at : 11
Destroyed : 0x602000008a38
Thread is joining...
x : 1
Destroyed : 0x104055020
Salin Konstruktor dan Pindahkan Konstruktor
Jika Anda memberikan pemindah dokumen, itu akan lebih disukai untuk setidaknya satu dari salinan tersebut:
#include <iostream>
#include <thread>
#include <functional>
using namespace std;
class tFunc{
int x;
public:
tFunc(){
cout<<"Constructed : "<<this<<endl;
x = 1;
}
tFunc(tFunc const& obj) : x(obj.x)
{
cout<<"Copy constructed : "<<this<< " (source=" << &obj << ')' << endl;
}
tFunc(tFunc&& obj) : x(obj.x)
{
cout<<"Move constructed : "<<this<< " (source=" << &obj << ')' << endl;
obj.x = 0;
}
~tFunc(){
cout<<"Destroyed : "<<this<<endl;
}
void operator()(){
x += 10;
cout<<"Thread running at : "<<x<<endl;
}
int getX() const { return x; }
};
int main()
{
tFunc t;
thread t1{t};
if(t1.joinable())
{
cout<<"Thread is joining..."<<endl;
t1.join();
}
cout<<"x : "<<t.getX()<<endl;
return 0;
}
Output (alamat bervariasi)
Constructed : 0x104057020
Copy constructed : 0x104057160 (source=0x104057020)
Move constructed : 0x602000008a38 (source=0x104057160)
Destroyed : 0x104057160
Thread running at : 11
Destroyed : 0x602000008a38
Thread is joining...
x : 1
Destroyed : 0x104057020
Referensi Dibungkus
Jika Anda ingin menghindari salinan itu, Anda dapat membungkus callable Anda dalam pembungkus referensi ( std::ref). Karena Anda ingin memanfaatkan tsetelah bagian threading selesai, ini layak untuk situasi Anda. Dalam praktiknya, Anda harus sangat berhati-hati ketika melakukan threading terhadap referensi untuk memanggil objek, karena umur objek harus meluas setidaknya selama utas menggunakan referensi.
#include <iostream>
#include <thread>
#include <functional>
using namespace std;
class tFunc{
int x;
public:
tFunc(){
cout<<"Constructed : "<<this<<endl;
x = 1;
}
tFunc(tFunc const& obj) : x(obj.x)
{
cout<<"Copy constructed : "<<this<< " (source=" << &obj << ')' << endl;
}
tFunc(tFunc&& obj) : x(obj.x)
{
cout<<"Move constructed : "<<this<< " (source=" << &obj << ')' << endl;
obj.x = 0;
}
~tFunc(){
cout<<"Destroyed : "<<this<<endl;
}
void operator()(){
x += 10;
cout<<"Thread running at : "<<x<<endl;
}
int getX() const { return x; }
};
int main()
{
tFunc t;
thread t1{std::ref(t)}; // LOOK HERE
if(t1.joinable())
{
cout<<"Thread is joining..."<<endl;
t1.join();
}
cout<<"x : "<<t.getX()<<endl;
return 0;
}
Output (alamat bervariasi)
Constructed : 0x104057020
Thread is joining...
Thread running at : 11
x : 11
Destroyed : 0x104057020
Catat meskipun saya menyimpan copy-ctor dan move-ctor kelebihan, tidak ada yang dipanggil, karena pembungkus referensi sekarang adalah hal yang sedang disalin / dipindahkan; bukan hal itu referensi. Juga, pendekatan akhir ini memberikan apa yang mungkin Anda cari; t.xkembali main, pada kenyataannya, dimodifikasi menjadi 11. Itu tidak dalam upaya sebelumnya. Namun, tidak dapat cukup menekankan hal ini: berhati-hatilah melakukan ini . Masa objek sangat penting .
Bergerak, Dan Tidak Ada Yang Lain
Akhirnya, jika Anda tidak tertarik untuk mempertahankan tseperti pada contoh Anda, Anda dapat menggunakan semantik bergerak untuk mengirim instance langsung ke utas, bergerak di sepanjang jalan.
#include <iostream>
#include <thread>
#include <functional>
using namespace std;
class tFunc{
int x;
public:
tFunc(){
cout<<"Constructed : "<<this<<endl;
x = 1;
}
tFunc(tFunc const& obj) : x(obj.x)
{
cout<<"Copy constructed : "<<this<< " (source=" << &obj << ')' << endl;
}
tFunc(tFunc&& obj) : x(obj.x)
{
cout<<"Move constructed : "<<this<< " (source=" << &obj << ')' << endl;
obj.x = 0;
}
~tFunc(){
cout<<"Destroyed : "<<this<<endl;
}
void operator()(){
x += 10;
cout<<"Thread running at : "<<x<<endl;
}
int getX() const { return x; }
};
int main()
{
thread t1{tFunc()}; // LOOK HERE
if(t1.joinable())
{
cout<<"Thread is joining..."<<endl;
t1.join();
}
return 0;
}
Output (alamat bervariasi)
Constructed : 0x104055040
Move constructed : 0x104055160 (source=0x104055040)
Move constructed : 0x602000008a38 (source=0x104055160)
Destroyed : 0x104055160
Destroyed : 0x104055040
Thread is joining...
Thread running at : 11
Destroyed : 0x602000008a38
Di sini Anda dapat melihat objek dibuat, referensi nilai untuk kata-sama kemudian dikirim langsung ke std::thread::thread(), di mana ia dipindahkan lagi ke tempat peristirahatan terakhir, yang dimiliki oleh utas dari titik itu ke depan. Tidak ada copy-ctors yang terlibat. Para pelaku sebenarnya menentang dua selongsong dan objek beton tujuan akhir.