2015-12-10 2 views
-2

C++ 11, VisualStudio 2015unordered_map копии вставки элементов

Мои unordered_map элементы являются указателями на класс. Вставка нового элемента не использует указатель, который я вставляю, но создал новый. Может ли кто-нибудь объяснить это поведение? (Я новичок в 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

Спасибо за понимание!

+1

Я не вижу 'unordered_map', который хранит указатели в любом месте вашего кода. – NathanOliver

+1

Если вы намеревались хранить указатели, объявление 'std :: unordered_map m_mLookupTables;' неверно. Правильное объявление: 'std :: unordered_map m_mLookupTables;' – ZDF

+0

ZDF и NathanOliver, вы совершенно правы. Моя карта имеет экземпляр элемента, а не указатель на него. Поэтому при вставке компилятора создается новый экземпляр и сохраняет его на карте! Спасибо! –

ответ

0

Б 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)); 
Смежные вопросы