在可能的情况下,经常重复不管理自己的内存。当编写一个管理地图或矢量中其他对象的对象时,应该如何创建对象并将其添加到其中。
如果你的对象管理使用新的和指针,这是有意义的。
// Manager::AddObj(Obj* obj);
// std::map<int, Obj*>
Obj* obj = new Obj();
obj->InitializeThings();
manager.AddObj(obj);
obj->CanStillDoThings();
但当不使用指针时,这有点。。。错误的我不确定正确的方法是什么。你最初制作的对象只用于复制到地图中。此外,如果你在管理器之外创建了那个对象,你就有点失去了它。因为你不想把它放进管理器中,然后再处理一个过时的对象。。!
// Manager::AddObj(Obj& obj);
// std::map<int, Obj>
Obj obj;
obj.DoAllocateyThings(); // copy ctor better be right!
manager.AddObj(obj);
obj.DoMoreStuff(); // this is not the same obj as the managed one!
Obj* real_obj = manager.GetObj();
我想一个解决方案是使用管理器来创建对象。那么丑陋只存在于经理内部。
Obj* Manager::CreateObj(){
Obj obj;
this->AddObj(1, obj);
return this->GetObj(1);
}
还有更好的方法吗?
让我们假设AddObj
调用std::map::insert
。如果是这样,那么你可以这样做:
#include <map>
#include <iostream>
class Obj
{
public:
int num;
Obj(int n = 0) : num(n) {}
};
std::map<int, Obj> m_ObjectMap;
Obj& CreateObj(int value)
{
Obj obj(value);
auto pr = m_ObjectMap.insert({1, obj});
return pr.first->second;
}
int main()
{
Obj& r = CreateObj(4);
std::cout << r.num << "n";
// verify that r is the actual reference to the object in the map
r.num = 100;
std::cout << m_ObjectMap[1].num << "n";
}
输出:
4
100
std::map::insert的返回值是一个表示插入项的迭代器的std::pair
,以及一个表示是否插入了新项的bool
。
由于std::map
迭代器是std::pair<key, data>
,所以所需的只是返回对该对的second
的引用。
唯一的问题是,如果该项目从std::map
中删除,如果你保留它,就会留下一个悬空的引用。这是另一回事。