企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
**一、事实1:只要用临时构造的A类对象作为参数传递给线程,那么一定能够在主线程执行完毕前把线程函数的第二个参数给构造出来** ``` #include "pch.h" #include <iostream> #include <thread> #include <string> using namespace std; class A { public : int m_i; //类型转换构造函数,就可以吧一个int转换成一个类A对象 A(int a) :m_i(a) { cout << "A构造函数执行" << endl; } A(const A &a) :m_i(a.m_i) { cout << "A拷贝构造函数执行" << endl; } ~A() { cout << "A析构函数" << endl; } }; //void myprint(const int &i, char *pmybuf) //void myprint(const int i, const std::string& pmybuf) void myprint(const int i, const A& pmybuf) { std::cout << i << std::endl; std::cout << &pmybuf << std::endl;//指针为detach时,绝对会有问题 return; } int main() { //一、传递临时对象作为线程参数 //(1,1)要避免的陷阱 //1. int mvar = 1; int &mvary = mvar; char mybuf[] = "this is test"; //thread mytobj(myprint, mvar, mybuf);//事实上存在mybuf都被回收了(main函数执行完了)系统采用mybuf转string(不可以) thread mytobj(myprint,mvar,A(mvar));//我们可以直接将mybuf转换成string对象,这是一个可以保证在线程中用肯定有效的 //在创建线程的同时构造临时对象的方法传递参数是可行的 mytobj.detach();//子线程和主线程分别执行 cout << "I Love You" << endl; std::cout << "Hello World!\n"; } ``` **二、临时对象作为线程参数** a、线程id的概念:id是个数字,每个线程(主线程,子线程)实际上都有对应一个数字唯一,线程id可以用c++标准库里的函数来获取,std::this_thread::get_id()来获取; b、临时对象构造时机捕获 **三、传递类对象,智能指针作为线程参数** a、std::ref函数;能把参数的真引用传递到函数中去;线程中不能使用detach ``` #include "pch.h" #include <iostream> #include <thread> #include <string> using namespace std; class A { public : int m_i; //类型转换构造函数,就可以吧一个int转换成一个类A对象 A(int a) :m_i(a) { cout << "A构造函数执行" << this << "线程id = " << std::this_thread::get_id() << endl; } A(const A &a) :m_i(a.m_i) { cout << "A拷贝构造函数执行" << this << "线程id = " << std::this_thread::get_id() << endl; } ~A() { cout << "A析构函数" << this << "线程id = " << std::this_thread::get_id() << endl; } }; //void myprint(const int &i, char *pmybuf) //void myprint(const int i, const std::string& pmybuf) //void myprint(const int i, const A& pmybuf) //如果没有用到std:ref的话 变量引用作为实参就需要加const void myprint(const int i, A& pmybuf) //加了std:ref { pmybuf.m_i = 100;//在没有加std::sef这个函数之前这个是没有的用的传递任何引用都没用 std::cout << "子线程的参数地址" << &pmybuf << "threadid = " << std::this_thread::get_id() << std::endl;//指针为detach时,绝对会有问题 return; } int main() { //**三、传递类对象,智能指针作为线程参数** // a、std::ref函数;用来修改子线程里面的临时拷贝的对象的成员变量; int mvar = 1; A mvarbuf(10); thread mytobj(myprint,mvar, std::ref(mvarbuf)); //在创建线程的同时构造临时对象的方法传递参数是可行的 mytobj.join();//子线程和主线程分别执行 cout << "主线程id = " << std::this_thread::get_id() << endl; std::cout << "Hello World!\n"; } ``` **使用智能指针作为参数以定不能使用detach;** ``` void myprint(unique_ptr<int> pzn) { return; } int main() { //智能指针 unique_ptr<int> myp(new int(10)); std::thread mytobj(myprint,std::move(myp));//需要使用std::move将智能指针传递到线程中qu mytobj.join(); std::cout << "Hello World!\n"; } ``` **四、用成员函数指针作为线程函数**