#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(int a) {
std::cout << "构造函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
A(const A& a) {
std::cout << "拷贝构造函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
~A() {
std::cout << "析构函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
public:
void run(int ab) {
std::cout << ab << std::endl;
std::cout << "子线程ID = " << std::this_thread::get_id() <<std::endl;
}
};
int main()
{
A a(1);
std::thread obj(&A::run, a, 1);
std::cout << "主线程ID = " << std::this_thread::get_id() << std::endl;
obj.join();
}
在上面的例程当中使用了非静态成员函数作为线程入口函数,同时传递了一个类对象和一个参数给线程对象obj。
来看下打印结果:
从结果可以看到,调用了拷贝构造函数,所以是复制了一个类对象到子线程当中执行的。并且复制的动作是在主线程当中执行的,而析构的动作是在子线程当中执行的。
如果传递的是&a我们再来看下现象如何:
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(int a) {
std::cout << "构造函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
A(const A& a) {
std::cout << "拷贝构造函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
~A() {
std::cout << "析构函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
public:
void run(int ab) {
std::cout << ab << std::endl;
std::cout << "子线程ID = " << std::this_thread::get_id() <<std::endl;
}
};
int main()
{
A a(1);
std::thread obj(&A::run, &a, 1);
std::cout << "主线程ID = " << std::this_thread::get_id() << std::endl;
obj.join();
}
从结果可以看出,没有调用拷贝构造函数,所以要注意了,必须要使用join了,避免主线程执行结束了,子线程还在使用类a对象。
我们再来看看使用std::ref
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(int a) {
std::cout << "构造函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
A(const A& a) {
std::cout << "拷贝构造函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
~A() {
std::cout << "析构函数执行了" << "this = " << this << " threadid = " << std::this_thread::get_id() << std::endl;
}
public:
void run(int ab) {
std::cout << ab << std::endl;
std::cout << "子线程ID = " << std::this_thread::get_id() <<std::endl;
}
};
int main()
{
A a(1);
std::thread obj(&A::run, std::ref(a), 1);
std::cout << "主线程ID = " << std::this_thread::get_id() << std::endl;
obj.join();
}
结果和使用&a是一样的。