C++ 对象在存储和检索无序映射后发生更改

C++ 对象在存储和检索无序映射后发生更改,c++,c++11,C++,C++11,考虑以下代码。我想使用mutex\u by\u name()创建和检索互斥体。锁不是一个真正的锁,但应该在一秒钟的间隙内完成它的工作 预期输出为m4.lock()失败lock FAILED,因为\u locked已设置为true。但它确实锁着。我是C++新手,我肯定我缺少一些明显的东西。你能解释一下如何正确地实施吗 #include <iostream> #include <string> #include <unordered_map> #include &

考虑以下代码。我想使用
mutex\u by\u name()
创建和检索互斥体。锁不是一个真正的锁,但应该在一秒钟的间隙内完成它的工作

预期输出为
m4.lock()
失败
lock FAILED
,因为
\u locked
已设置为true。但它确实锁着。我是C++新手,我肯定我缺少一些明显的东西。你能解释一下如何正确地实施吗

#include <iostream>
#include <string>
#include <unordered_map>
#include <unistd.h>

class Mutex {
private:
    int _id;
    bool _locked = false;
    void status(std::string s) {
        std::cout << _id << " " << name << " " << s << " " << std::endl;
    }
public:
    const std::string name;
    Mutex(std::string name): name(name) {
        static int id = 0;
        _id = id++;
        status("created");
    }
    Mutex(const Mutex& m): _id(m._id), _locked(m._locked), name(m.name) {
        status("copy-constructed");
    }
    Mutex(Mutex&& m) = delete;
    void operator=(Mutex&) = delete;
    ~Mutex() {
        status("deleted");
    }
    void lock() {
        // YES, THIS IS NOT A REAL AND SAFE LOCK
        if (!_locked) {
            _locked = true;
            status("locked");
        } else {
            status("lock FAILED");
        }
    }
};

std::unordered_map<std::string, Mutex> mutexe;

Mutex& mutex_by_name(std::string name) {
    mutexe.emplace(name, Mutex(name));
    auto found = mutexe.find(name);
    return found->second;
}


using namespace std;

int main() {
    cout << "# 1" << endl;
    Mutex m1 = mutex_by_name("hello");
    m1.lock();
    sleep(1);

    cout << "# 2" << endl;
    Mutex m4 = mutex_by_name("hello");
    m4.lock();
    sleep(1);
}
#包括
#包括
#包括
#包括
类互斥{
私人:
内部id;
bool _locked=false;
无效状态(标准::字符串s){

std::cout主要需要进行m1和m4引用(互斥和m1)。现在它们是副本,因此不会更新无序映射中的值。

主要需要进行m1和m4引用(互斥和m1)。现在它们是副本,因此不会更新无序映射中的值。

主要需要进行m1和m4引用(互斥体和m1)。现在它们是副本,因此不会更新无序映射中的值。

主要需要进行m1和m4引用(互斥体和m1)。现在它们是副本,因此不会更新无序映射中的值。

您必须解决问题。首先,您没有将
m1
m4
声明为引用,它们应该是引用

其次,代码样式:)

因此,这将解决它:

Mutex &m1 = mutex_by_name("hello");

//...

Mutex &m4 = mutex_by_name("hello");

你必须解决问题。首先,你不能将
m1
m4
声明为引用,它们应该是引用

其次,代码样式:)

因此,这将解决它:

Mutex &m1 = mutex_by_name("hello");

//...

Mutex &m4 = mutex_by_name("hello");

你必须解决问题。首先,你不能将
m1
m4
声明为引用,它们应该是引用

其次,代码样式:)

因此,这将解决它:

Mutex &m1 = mutex_by_name("hello");

//...

Mutex &m4 = mutex_by_name("hello");

你必须解决问题。首先,你不能将
m1
m4
声明为引用,它们应该是引用

其次,代码样式:)

因此,这将解决它:

Mutex &m1 = mutex_by_name("hello");

//...

Mutex &m4 = mutex_by_name("hello");

它解决了问题。但我真的不明白为什么。复制发生在哪里?为什么编译器不抱怨分配互斥体&给互斥体?@valyron:a
互斥体&
可能被分配给
互斥体
,在这种情况下会发生复制。在您的行“Mutex m1=Mutex by_name(“hello”);”你告诉编译器m1是它自己的对象。在这种情况下,引用被视为普通对象,而不是它所在的指针。m1是使用复制构造函数构造的。编译器没有抱怨,因为它完全合法。你是说“我想创建一个新对象m1,其中引用的内容由mutex_按_name返回“?有意义吗?好的,我理解这一点,但在我的复制构造函数中,
\u locked
被复制到新实例,那么为什么不起作用呢?它是按值复制的。\u locked in m1、m4和映射中的互斥体都有单独的内存位置。更新一个不会影响其他任何一个(除非您使它们引用)。它解决了问题。但我真的不明白为什么。复制发生在哪里?为什么编译器不抱怨分配互斥体&给互斥体?@valyron:a
互斥体&
可能被分配给
互斥体
,在这种情况下会发生复制。在您的行中“Mutex m1=Mutex\u by\u name(“hello”);”你告诉编译器m1是它自己的对象。在这种情况下,引用被视为普通对象,而不是它所在的指针。m1是使用复制构造函数构造的。编译器没有抱怨,因为它完全合法。你是说“我想创建一个新对象m1,其中引用的内容由mutex_按_name返回“?有意义吗?好的,我理解这一点,但在我的复制构造函数中,
\u locked
被复制到新实例,那么为什么不起作用呢?它是按值复制的。\u locked in m1、m4和映射中的互斥体都有单独的内存位置。更新一个不会影响其他任何一个(除非您使它们引用)。它解决了问题。但我真的不明白为什么。复制发生在哪里?为什么编译器不抱怨分配互斥体&给互斥体?@valyron:a
互斥体&
可能被分配给
互斥体
,在这种情况下会发生复制。在您的行中“Mutex m1=Mutex\u by\u name(“hello”);”你告诉编译器m1是它自己的对象。在这种情况下,引用被视为普通对象,而不是它所在的指针。m1是使用复制构造函数构造的。编译器没有抱怨,因为它完全合法。你是说“我想创建一个新对象m1,其中引用的内容由mutex_按_name返回“?有意义吗?好的,我理解这一点,但在我的复制构造函数中,
\u locked
被复制到新实例,那么为什么不起作用呢?它是按值复制的。\u locked in m1、m4和映射中的互斥体都有单独的内存位置。更新一个不会影响其他任何一个(除非您使它们引用)。它解决了问题。但我真的不明白为什么。复制发生在哪里?为什么编译器不抱怨分配互斥体&给互斥体?@valyron:a
互斥体&
可能被分配给
互斥体
,在这种情况下会发生复制。在您的行中“Mutex m1=Mutex\u by\u name(“hello”);”你告诉编译器m1是它自己的对象。在这种情况下,引用被视为普通对象,而不是它所在的指针。m1是使用复制构造函数构造的。编译器没有抱怨,因为它完全合法。你是说“我想创建一个新对象m1,其中引用的内容由互斥对象名称返回”?有意义吗?好的,我理解,但在我的复制构造函数中,
\u locked
被复制到新实例,为什么不起作用?它是按值复制的