C++线程调用类成员函数修改类成员值的问题及代码示例
问题分析与解决方案
嘿,我一眼就发现你代码里的问题啦——你创建线程时传递的是对象f的副本,所以线程中assign_value()修改的是那个副本的value,完全碰不到主函数里原对象f的成员变量!
为什么会这样?
当你写thread t1(&foo::assign_value, f);时,std::thread会自动把f复制一份,线程执行成员函数时,操作的是这个拷贝出来的临时对象。所以主函数里的f.value还是未初始化的状态(会输出随机值,属于未定义行为),和线程里修改的不是同一个东西。
两种解决办法
1. 传递对象引用(用std::ref包装)
通过std::ref把对象包装成引用类型,这样线程就会直接操作原对象,而不是创建副本。注意要包含<functional>头文件来使用std::ref:
#include <thread> #include <iostream> #include <functional> using namespace std; class foo { public: void assign_value(); int value = 0; // 给成员变量初始化,避免未定义行为 }; void foo::assign_value() { value = 1; cout << "value within assign_value() is " << value << '\n'; } int main() { foo f; thread t1(&foo::assign_value, std::ref(f)); // 用std::ref传递引用 t1.join(); cout << "value in main is " << f.value << '\n'; return 0; }
2. 传递对象指针
直接把原对象的地址传给线程,成员函数会把这个指针作为this指针来使用,自然就操作原对象了,这种方式不需要额外头文件:
#include <thread> #include <iostream> using namespace std; class foo { public: void assign_value(); int value = 0; }; void foo::assign_value() { value = 1; cout << "value within assign_value() is " << value << '\n'; } int main() { foo f; thread t1(&foo::assign_value, &f); // 传递对象指针 t1.join(); cout << "value in main is " << f.value << '\n'; return 0; }
额外提示
记得给成员变量value初始化(比如int value = 0;),不然原对象的value是未初始化的,会触发未定义行为,输出的结果不可预测。
内容的提问来源于stack exchange,提问作者USC
相关产品推荐
相关产品推荐

