2017-06-01 103 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>