2017-06-01 66 views
-1

我遇到了一些奇怪的问题。我有班级,它的值存储在地图中。但在一种情况下,我需要公开地图来做一些外部计算,并可能在该地图内添加数据。地图参考混淆

而我有下一个问题。我有该类的shared_ptr并通过引用公开地图,但在处理地图过程中不会接受新数据。

我写了一些虚构的例子,只是要清楚。这里发生了什么?为什么?

为什么地图变化不会在函数结束后保留​​?

#include <map> 
#include <iostream> 
#include <memory> 

class MapWrap { 
public: 
    MapWrap() {} 
    ~MapWrap(){} 

    std::map<int, int>& getMap() { return map; } 
private: 
    std::map<int, int> map; 
}; 

void goGo(std::shared_ptr<MapWrap> m){ 
    auto map = m->getMap(); 
    std::cout << "Func: before: map size: " << map.size() << std::endl; 

    for(int i = 0; i < 3; ++i){ 
    // This should and will add new value to map. 
    if(map[i] == 3){ 
     std::cout << "blah" << std::endl; 
    } 
    } 

    std::cout << "Func: after: map size: " << map.size() << std::endl; 
} 

int main(){ 

    auto mapWrap = std::make_shared<MapWrap>(); 

    for(int i = 0; i < 3; ++i){ 
    goGo(mapWrap); 
    } 

    return 0; 
} 

编辑:从getMap()方法中删除const。

+1

如果您不想共享所有权,请不要将shared_ptr用作参数。如果参数不是空的,请使用原始指针或更好的引用。 – 2017-06-01 12:37:49

回答

3

的问题是,在这里:

auto map = m->getMap(); 

类型的地图为std::map<int, int>所以你犯了一个副本,并修改该副本。将其更改为:

auto& map = m->getMap(); 

并且您将修改传递的映射而不是副本。

btw。如果你不知道什么类型的自动变量有,你可以随时使用的编译器错误检查:

template<typename T> struct TD; 

auto map = m->getMap(); 
TD<decltype(map)> dd; 

将导致:

main.cpp:19:21: error: aggregate 'TD<std::map<int, int> > dd' has incomplete type and cannot be defined 
    TD<decltype(map)> dd; 

在这里你可以阅读map类型为std::map<int, int>