C++多线程创建临时对象:类对象隐式转换和显示转换,引用传参和直接传参测试

1.隐式转换

#include<iostream>
#include<thread>

using namespace std;


//主线程使用类建立对象,执行顺序测试
class A {
public:
	int m_i;
	//类型转换构造函数,可以把int整型转换成类A对象
	A(int a) :m_i(a) { cout << "A::A(int a)构造函数执行!, 地址是:" << this << "  构造函数线程id是:" << std::this_thread::get_id() << endl; }
	A(const A &a) :m_i(a.m_i) { cout << "A::A(const A)拷贝构造函数执行!地址是:" <<this <<"  拷贝构造函数线程id是:" << std::this_thread::get_id() << endl; }
	~A(){ cout << "A::~A()析构函数执行!" << endl; }
};

void myPrint2(const int i, const A &buf)
{
	cout << "引用的对象地址是"<< &buf << endl;
	cout << "myPrint线程id是" << std::this_thread::get_id() << endl;
	return;
}
int main()
{
	cout << "主线程ID是"<<std::this_thread::get_id() << endl;

	int marv = 1;
	int mySecondPar = 10;
	//显示转换,thread启动时就创建临时对象
	//thread thread2(myPrint2, marv, A(mySecondPar));
	//隐式转换
	thread thread2(myPrint2, marv, mySecondPar);
	
	thread2.join();
	//thread2.detach();	
	return 0;
}
``
![在这里插入图片描述](https://img-blog.csdnimg.cn/a58850ab985c47f0bbe54909838af7e2.png)
隐式转换,类对象在子线程里面创建,会带来一定隐患

```cpp
#include<iostream>
#include<thread>

using namespace std;


//主线程使用类建立对象,执行顺序测试
class A {
public:
	int m_i;
	//类型转换构造函数,可以把int整型转换成类A对象
	A(int a) :m_i(a) { cout << "A::A(int a)构造函数执行!, 地址是:" << this << "  构造函数线程id是:" << std::this_thread::get_id() << endl; }
	A(const A &a) :m_i(a.m_i) { cout << "A::A(const A)拷贝构造函数执行!地址是:" <<this <<"  拷贝构造函数线程id是:" << std::this_thread::get_id() << endl; }
	~A(){ cout << "A::~A()析构函数执行!" << endl; }
};

void myPrint2(const int i, const A &buf)
{
	cout << "引用的对象地址是"<< &buf << endl;
	cout << "myPrint线程id是" << std::this_thread::get_id() << endl;
	return;
}
int main()
{
	cout << "主线程ID是"<<std::this_thread::get_id() << endl;

	int marv = 1;
	int mySecondPar = 10;
	//显示转换,thread启动时就创建临时对象
	thread thread2(myPrint2, marv, A(mySecondPar));
	//隐式转换
	//thread thread2(myPrint2, marv, mySecondPar);
	
	thread2.join();
	//thread2.detach();	
	return 0;
}```
![在这里插入图片描述](https://img-blog.csdnimg.cn/77f3ece4402a4dcd8f39bffb429f8ee0.png)
引用传参与直接传参的区别
引用传参:类显示转换时,类的构造函数和拷贝构造函数各执行一次。构造函数和拷贝构造函数的所属线程id与主线程一样,说明构造函数在主线程中执行一次,拷贝构造函数在主线程执行一次;见上图
直接传参:类显示转换时,类的构造函数执行一次,拷贝构造函数执行两次次。构造函数在主线程中执行一次,拷贝构造函数在主线程和子线程执行一次;见下图

```cpp
#include<iostream>
#include<thread>

using namespace std;


//主线程使用类建立对象,执行顺序测试
class A {
public:
	int m_i;
	//类型转换构造函数,可以把int整型转换成类A对象
	A(int a) :m_i(a) { cout << "A::A(int a)构造函数执行!, 地址是:" << this << "  构造函数线程id是:" << std::this_thread::get_id() << endl; }
	A(const A &a) :m_i(a.m_i) { cout << "A::A(const A)拷贝构造函数执行!地址是:" <<this <<"  拷贝构造函数线程id是:" << std::this_thread::get_id() << endl; }
	~A(){ cout << "A::~A()析构函数执行!" << endl; }
};

//引用传参
//void myPrint2(const int i, const A &buf)
//直接传参
void myPrint2(const int i, const A buf)
{
	cout << "引用的对象地址是"<< &buf << endl;
	cout << "myPrint线程id是" << std::this_thread::get_id() << endl;
	return;
}
int main()
{
	cout << "主线程ID是"<<std::this_thread::get_id() << endl;

	int marv = 1;
	int mySecondPar = 10;
	//显示转换,thread启动时就创建临时对象
	thread thread2(myPrint2, marv, A(mySecondPar));
	//隐式转换
	//thread thread2(myPrint2, marv, mySecondPar);
	
	thread2.join();
	//thread2.detach();	
	return 0;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/dd81346463ea4cbb84e5810ca7d39644.png#pic_center)

```cpp
#include <iostream>
#include <thread>
using namespace std;

class A {
public:
	mutable int m_i; //m_i即使实在const中也可以被修改
	A(int i) :m_i(i) {}
};

void myPrint(const A& pmybuf)
{
	pmybuf.m_i = 199;
	cout << "子线程myPrint的参数地址是" << &pmybuf << "thread = " << std::this_thread::get_id() << endl;
}

int main()
{
	A myObj(10);
	//myPrint(const A& pmybuf)中引用不能去掉,如果去掉会多创建一个对象
	//const也不能去掉,去掉会出错
	//即使是传递的const引用,但在子线程中还是会调用拷贝构造函数构造一个新的对象,
	//所以在子线程中修改m_i的值不会影响到主线程
	//如果希望子线程中修改m_i的值影响到主线程,可以用thread myThread(myPrint, std::ref(myObj));
	//这样const就是真的引用了,myPrint定义中的const就可以去掉了,类A定义中的mutable也可以去掉了
	thread myThread(myPrint, myObj);
	myThread.join();
	//myThread.detach();

	cout << "Hello World!" << endl;
}
#include <iostream>
#include <thread>
#include <memory>
using namespace std;

void myPrint(unique_ptr<int> ptn)
{
	cout << "thread = " << std::this_thread::get_id() << endl;
}

int main()
{
	unique_ptr<int> up(new int(10));
	//独占式指针只能通过std::move()才可以传递给另一个指针
	//传递后up就指向空,新的ptn指向原来的内存
	//所以这时就不能用detach了,因为如果主线程先执行完,ptn指向的对象就被释放了
	thread myThread(myPrint, std::move(up));
	myThread.join();
	//myThread.detach();

	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值