Is there a way to remove a key from a C ++ card without deleting the content?

I have a class called Shape and a ShapeStorage class. The ShapeStorage class has a map ...

std::map<int, Shape*> shapes; 

and function ...

 Shape * ReturnShapePointer(int key) { Shape* shape = shapes[key]; shapes.erase(key); return shape; } 

My goal is for my main class to instantiate a ShapeStorage object, save some shape * on the shape map. Then later I want to delete it from my card, but not delete it. I want my main class to still be able to access the value.

I tried to do this and my pointer still returns the correct values, but I'm afraid that since the destructor is called for Shape when I delete the pointer from my map, so this is just garbage of data at this point.

Is there any way around this?

+4
source share
7 answers

If you store pointers, map will not call your destructor. If he is called, he will be called to another place.

Try this example:

 #include <iostream> #include <map> class Shape { public: ~Shape() { std::cout << "Shape deleted" << std::endl; } }; int main(int argc, char *argv[]) { std::map<int, Shape *> shapes; shapes[1] = new Shape(); std::cout << "Shape added" << std::endl; shapes.erase(1); std::cout << "Shape removed from map, now exiting" << std::endl; } 

You should get the following:

 Shape added Shape removed from map, now exiting 
+4
source

Your map only contains pointers to Shape s. Removing the pointer from the map does not affect the object it points to, but only destroys the pointer on the map.

In addition, your function will perform a key search twice. Once when using operator [] and a second time when calling erase () with the key. Here is the best way to do this:

 Shape *ReturnShapePointer (int key) { Shape *shape; std::map<int, Shape*>::iterator it = shapes.find (key); if (it != shapes.end ()) { shape = it->second; shapes.erase (it); } else { shape = NULL; } return shape; } 
+3
source
 Shape* shape = shapes[key]; shapes.erase(key); //you can use shape here, without any problem! 

It's fine. You can safely use the shape variable.

In fact, you are responsible for the delete shape . This is not the responsibility of std::map .

+1
source

std::map will not delete pointers that it contains automatically.

0
source

All STL containers store values - pointers in your case. Thus, a destructor (not a deconstructor :) for Shape not called when deleting a record.

0
source
 Shape * ReturnShapePointer(int key) { Shape* shape = shapes[key]; shapes.erase(key); return shape; } 

I'm afraid that since the deconstructor is called for Shape, when I remove the pointer from my map,

Above code does not delete the Shape object. He only removes it from the card, which seems to be exactly what you want.

0
source

When you call erase on a pointer, the destructor is not called, so you current solution should work fine.

STL has value semantics, not referential semantics. Thus, a copy of your pointer is created when pasted onto the map. The copy will die off, but your original will still point to the same memory location as always, and the value will still be present in this place until you delete it with the pointer (or until this value comes out from scope, if it was based on the stack, and the pointer was set using the and operator).

0
source

Source: https://habr.com/ru/post/1384181/


All Articles