Reputation: 1881
I have objects of type MyClass stored as pairs <std::string, MyClass>
in an STL Map. The std::string is a unique name for each MyClass object. I want every MyClass object to be instantiated only ONCE per name and thus destroyed only once at the end in my application. So I try to avoid invocation of copy constructors or default constructors, as they might invoke destruction. A MyClass object refers to some kind of ressource that shall be allocated/freed only once. I tried to use this code to create instances of MyClass, put them in my map and give a pointer to the just created instance back.
MyClass* FooClass::GetItem(std::string name)
{
MyClass* item = GetItemExists(name);
if (item == NULL)
{
item = &(*((this->myMap.insert(std::pair<std::string, MyClass>
(name, MyClass(name)))).first)).second;
}
return item;
}
Creation and insertion works this way. But the destructor of Class MyClass is called 3! times. Even the return item;
statement invokes the destructor, as this is a pointer?! I thought this is impossible and must be forced by delete item
?!
I thought an alternative is to store pointers MyClass* instead of objects in the map. Or is there a better alternative? I did not use myMap[name] = MyClass(name);
to avoid copy/destruction, but I think insert doesnt make it better.
Upvotes: 1
Views: 1400
Reputation: 157334
You need to emplace and piecewise construct the inserted element:
item = &(this->myMap.emplace(std::piecewise_construct,
std::forward_as_tuple(name),
std::forward_as_tuple(name)).first->second);
Upvotes: 1