C++ 如何将对象添加到地图和 return 引用地图中新创建的对象

C++ How to add objects to maps and return reference to new created object inside map

下面我提供了我正在努力解决的非常简单的事情的完整代码..

请查看下面我说的两条评论"ERROR",看看问题出在哪里。

我的问题是:

  1. 如何将一个对象插入地图?这条线有什么问题 在 InitObj()?
  2. 如何创建 return 对我刚刚创建的对象的引用 在地图上创建?如 getHouse() 函数末尾所示

提前致谢:)

#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;
}

对于您的第一个问题,您使 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)return一个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;