我的类有一个用户定义类型的变量。我在这个类的一个方法中设置了这个变量。当我尝试从同一个类的另一个方法获取此变量时,该值始终为0,尽管该变量在其他任何位置都没有更改。
我真的不明白为什么会这样! Follwoing是我的代码示例:
myclass.h
typedef enum {
ACTIVE = 0,
SLEEP = 1,
FINISHED = 2,
WAITING = 3,
KILLED = 4
} Mode;
class MyClass
{
public:
void statusReceive(void);
Mode getCurrentMode(void);
private:
Mode currentMode;
};
myclass.cpp
#include "myclass.h"
void MyClass::statusReceive(void)
{
currentMode = (Mode)interpretMsg(&msg);
printf("current Mode = %d\n", this->currentMode); // prints 4
}
Mode MyClass::getCurrentMode(void)
{
printf("current Mode = %d\n", this->currentMode); // prints 0
return this->currentMode;
}
的main.cpp
#include "myclass.h"
MyClass myclass;
void timerStart(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
int main(void)
{
timerStart(std::bind(&MyClass::statusReceive, myclass), 10);
Mode x = myclass.getCurrentMode();
printf("Current Mode = %d\n", x); // prints 0
}
答案 0 :(得分:1)
我发现此代码存在两个问题。
首先,std::bind
复制(或移动)其所有参数。因此,从bind
返回的仿函数值包含另一个MyClass
对象,该对象是从myclass
对象复制构造的,对该仿函数的调用只会更改内部MyClass
,而不是myclass
。
您可以使用引用包装器指定使用相同的MyClass
对象:
timerStart(std::bind(&MyClass::statusReceive, std::ref(myclass)), 10);
或只是切换到lambda直接调用myclass
上的成员函数:
timerStart([](){ myclass.statusReceive(); }, 10);
其次,您正在修改一个线程中的myclass.currentMode
对象并在另一个线程中读取它,而两个操作之间没有任何同步。这是一种数据竞争和未定义的行为。