unordered_map 插入复制元素

unordered_map insert copies element

C++11,VisualStudio 2015

我的 unordered_map 元素是指向 class 的指针。 插入新元素并没有使用我插入的指针,而是创建了一个新元素。 谁能解释这种行为? (我是 C++11 的新手,但有多年的 Java 经验,所以你明白为什么我觉得它很奇怪!)。

///// test_map.h

#pragma once
#include <string>
#include <unordered_map>

class CLookupTables {
public:
    CLookupTables();
    CLookupTables(std::wstring domain, CLookupTables* parent);
    ~CLookupTables();

    std::wstring getDomain();
    void setNum(std::wstring from, std::wstring to);
private:
    std::wstring m_domain;
    std::unordered_map<std::wstring, std::wstring> m_NUM;   
    CLookupTables * m_parent;
};
class CConfiguration
{
public:
    CConfiguration();
    ~CConfiguration();

    // initialize all from DB
    void initializeDbTables();
private:
    std::unordered_map<std::wstring, CLookupTables> m_mLookupTables;
};

/////// test_map.cpp

#include "test_map.h"
CLookupTables::~CLookupTables()
{
}
CLookupTables::CLookupTables()
{
    m_domain = L"";
    m_parent = nullptr;
    m_NUM.clear();
}

CLookupTables::CLookupTables(std::wstring domain, CLookupTables* parent)
{
    m_domain = domain;
    m_parent = parent;
    m_NUM.clear();
}
std::wstring CLookupTables::getDomain()
{
    return m_domain;
}

void CLookupTables::setNum(std::wstring from, std::wstring to)
{
    m_NUM[from] = to;
}


CConfiguration::CConfiguration()
{
    m_mLookupTables.clear();
}
CConfiguration::~CConfiguration()
{
}

std::wstring  C_defaultDomain = L"roman";

void CConfiguration::initializeDbTables()
{
    std::wstring domain = C_defaultDomain;
    CLookupTables *defaultLookupTable = new CLookupTables(C_defaultDomain, nullptr);

    // the map is empty at this point; no need to "find" existing key here
    auto pair = std::make_pair(domain, *defaultLookupTable);
    auto insPair = m_mLookupTables.insert(pair);

    // this will NOT insert the value to the map inside m_mLookupTables
    defaultLookupTable->setNum(L"V", L"five");

    // for some inexplicable C++ reason, defaultLookupTable pointer is DIFFERENT 
    // than the one created above and inserted into the map
    defaultLookupTable = &(m_mLookupTables.find(domain)->second);
    // is this a memory leak?

    // now value will be in m_mLookupTables 
    defaultLookupTable->setNum(L"X", L"ten");
}

///////// 主要测试

#include "stdafx.h"
#include "test_map.h"
int main()
{
    CConfiguration * cconf = new CConfiguration();
    cconf->initializeDbTables();
}

此代码可以在 Windows 10 VisualStudio 2015

上按原样运行

感谢您的见解!

使用 ZDF 和 NatahnOliver 评论:

要么使用

std::unordered_map<std::wstring, CLookupTables *> m_mLookupTables;
...
auto pair = std::make_pair(domain, defaultLookupTable);
... etc

或使用

 auto insPair = m_mLookupTables.emplace(domain, CLookupTables(C_defaultDomain, parent));