类方法读取相同变量C ++的不同值

时间:2017-10-28 21:33:15

标签: c++ oop

我的类有一个用户定义类型的变量。我在这个类的一个方法中设置了这个变量。当我尝试从同一个类的另一个方法获取此变量时,该值始终为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
}

1 个答案:

答案 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对象并在另一个线程中读取它,而两个操作之间没有任何同步。这是一种数据竞争和未定义的行为。