Bạn đang thiếu thiết bị sao chép xây dựng và di chuyển xây dựng. Một sửa đổi đơn giản cho chương trình của bạn sẽ cung cấp bằng chứng đó là nơi các công trình đang diễn ra.
Sao chép xây dựng
#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;
}
Đầu ra (địa chỉ khác nhau)
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
Sao chép Trình xây dựng và Di chuyển Trình xây dựng
Nếu bạn cung cấp một ctor di chuyển, nó sẽ được ưu tiên cho ít nhất một trong những bản sao khác:
#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;
}
Đầu ra (địa chỉ khác nhau)
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
Tham khảo gói
Nếu bạn muốn tránh những bản sao đó, bạn có thể gói có thể gọi được trong một trình bao bọc tham chiếu ( std::ref
). Vì bạn muốn sử dụng t
sau khi hoàn thành phần xâu chuỗi, điều này khả thi cho tình huống của bạn. Trong thực tế, bạn phải rất cẩn thận khi xâu chuỗi các tham chiếu để gọi các đối tượng, vì thời gian tồn tại của đối tượng phải kéo dài ít nhất là khi luồng sử dụng tham chiếu.
#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;
}
Đầu ra (địa chỉ khác nhau)
Constructed : 0x104057020
Thread is joining...
Thread running at : 11
x : 11
Destroyed : 0x104057020
Lưu ý mặc dù tôi đã giữ quá tải copy-ctor và move-ctor, nhưng không được gọi, vì trình bao bọc tham chiếu bây giờ là thứ được sao chép / di chuyển; không phải là thứ nó tham khảo. Ngoài ra, phương pháp cuối cùng này cung cấp những gì bạn có thể đang tìm kiếm; t.x
trở lại trong main
là, trên thực tế, sửa đổi để 11
. Đó không phải là trong những nỗ lực trước đó. Tuy nhiên, không thể nhấn mạnh điều này đủ: hãy cẩn thận khi làm điều này . Đối tượng trọn đời là rất quan trọng .
Di chuyển, và không có gì nhưng
Cuối cùng, nếu bạn không có hứng thú với việc giữ lại t
như trong ví dụ của mình, bạn có thể sử dụng ngữ nghĩa di chuyển để gửi cá thể thẳng đến luồng, di chuyển dọc đường.
#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;
}
Đầu ra (địa chỉ khác nhau)
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
Ở đây bạn có thể thấy đối tượng được tạo ra, tham chiếu giá trị cho cùng nói sau đó được gửi thẳng đến std::thread::thread()
, nơi nó được di chuyển trở lại nơi an nghỉ cuối cùng của nó, thuộc sở hữu của luồng từ thời điểm đó trở đi. Không có bản sao có liên quan. Các dtor thực tế chống lại hai vỏ và vật thể bê tông đích cuối cùng.