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 t
setelah 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.x
kembali 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 t
seperti 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.