C ++如何将对象添加到地图并返回对地图内新创建对象的引用

时间:2015-06-20 17:10:35

标签: c++ dictionary shared-ptr

Bellow我提供了一些非常简单的完整代码,我正在努力...

  • 我需要创建一个包含字符串和对象的地图......
  • 当请求时,如果字符串在地图内,我需要返回一个 引用地图中的一个对象
  • 当字符串不在地图中时,我需要创建该对象, 使用该字符串并返回(如前所述)对新的引用 创建对象

请在下面查看我说“错误”的两条评论,以查看问题所在。

我的问题是:

  1. 如何将一个对象插入地图?这条线有什么问题 在InitObj()?
  2. 如何创建返回对我刚才的对象的引用 在地图上创建?如在getHouse()函数结束时所见
  3. 提前致谢:)

    #include <map>
    #include <string>
    #include <memory>
    
    class House
    {
    public:
    
        House(const char* name) : _name(name) {};
        ~House() {};
    
        std::string getHouseName () { return _name; }
    private:
        std::string _name;
    
        House(const House& copy)
        {
        }
        House& operator=(const House& assign)
        {
        }
    };
    
    class Obj
    {
    public:
        Obj()
        {
            InitObj();
        }
        ~Obj() {};
    
        House& getHouse (const char *houseName)
        {
            std::string name = houseName;
            auto i = _myHouseMap.find(name);
    
            //this string doesn't exist on map? then create a new house and add to the map and return the reference to it
            if (i == _myHouseMap.end())
            {
                //create a new house
                House h(houseName); 
    
                //add to the map
                _myHouseMap.insert(std::pair<const std::string, House>(houseName, h));
    
                //return the reference to the house created
                return h; //<--- ERROR!!!! need to return the reference!
            }
            return (i->second);
        }
    
    
    
    private:
        Obj(const Obj& copy);
        Obj& operator=(const Obj& assign);
    
        typedef std::map<const std::string, House> myHouseMap;
    
        myHouseMap _myHouseMap;
    
        //the initialization will add one object to my map
        void InitObj()
        {
            House h("apartment");
            _myHouseMap.insert(std::pair<const std::string, House>("apartment", h)); //<--- ERROR see reference to function template instantiation 'std::pair<_Ty1,_Ty2>::pair<const char(&)[10],House&>
        }
    };
    
    
    int main(void)
    {
        Obj aaa;
    
        House& myHouse1 = aaa.getHouse ("apartment");
        std::cout << "House is " << myHouse1.getHouseName ();
    
        House& myHouse2 = aaa.getHouse ("newHouse"); //here a new house must be created and added to the map
        std::cout << "House is " << myHouse2.getHouseName ();
    
        return 0;
    }
    

1 个答案:

答案 0 :(得分:3)

对于您的第一个问题,您使House不可复制(您的复制构造函数和复制赋值运算符是私有的)。您要对insert采取的方法要求您首先制作pair,其构造将复制您传入的House。如果您有权访问对于C ++ 11编译器,您仍然可以将地图的值类型设为House,而只需使用emplace

void InitObj()
{
    _myHouseMap.emplace(std::piecewise_construct,
                        std::forward_as_tuple("apartment"),  //key
                        std::forward_as_tuple("apartment")); //value
}    

如果您无法访问C ++ 11编译器,则必须将值类型更改为House*或某些等效的可复制构造类型。

对于第二个问题,std::map::insert(和emplace)会返回pair<iterator, bool>。只是利用这个:

if (i == _myHouseMap.end())
{
    House h(houseName); 

    // we insert our new house into the map
    // insert() will return a pair<iterator, bool>. 
    // the bool will be true if the insert succeeded - which we know
    // it will because we know that this key isn't already in the map
    // so we just reassign 'i' to be insert().first, the new iterator
    // pointing to the newly inserted element
    i = _myHouseMap.insert(std::pair<const std::string, House>(houseName, h)).first;
}

// here i either points to the element that was already in the map
// or the new element that we just inserted. either way, 
// we want the same thing
return i->second;