
先看代码:
#include <iostream>
#include <thread>
#include <string>
using namespace std;
class B
{
public:
int age = 18;
void Say()
{
std::cout << "Say B" << std::endl;
}
};
class A
{
public:
int age = 10;
void Say()
{
std::cout << "Say A" << std::endl;
}
void Start()
{
B b;
std::thread t(&A::_start,this);
t.detach();
}
private:
void _start()
{
age++;
std::cout << "A.age=" <<age<< std::endl;
Say();
}
};
int main()
{
A a;
a.age = 22;
a.Start();
std::cout << "main thread " << a.age << std::endl;
}输出结果:
main thread 22 A.age=1 Say A
这个输出似乎在_start函数里面,类A的成员age被清空了,变成0,age++后变成1了。难道是不能在线程函数里面改变类对象的值吗。我查阅了很多资料都没解决。即使传递指针等都不行。最后发现一个神奇现象,代码如下:
#include <iostream>
#include <thread>
#include <windows.h>
#include <string>
using namespace std;
class B
{
public:
int age = 18;
void Say()
{
std::cout << "Say B" << std::endl;
}
};
class A
{
public:
int age = 10;
void Say()
{
std::cout << "Say A" << std::endl;
}
void Start()
{
B b;
std::thread t(&A::_start,this);
t.detach();
}
private:
void _start()
{
age++;
std::cout << "A.age=" <<age<< std::endl;
Say();
}
};
int main()
{
A a;
a.age = 22;
a.Start();
Sleep(3000);
std::cout << "main thread " << a.age << std::endl;
}输出:
A.age=23 Say A main thread 23
这回居然变了。就加了个延时,可以得出结论是,主进程运行立马退出后,线程函数来不及给类成员变量赋值?导致age变量是0,可能线程函数对age这个变量做了一些拷贝操作,导致不是原来的值。目前只能这么理解。总结:
(1)std::thread线程函数中可以直接改变类的成员变量,但是不是立马就可以改变,如果主线程过快退出,会造成类的成员变量无法改变的假象。这样你就入坑了,怎么也找不到变量为啥是0的原因。