[英]Is there a way to remove a key from a C++ map without deleting the contents?
我有一个名为Shape的类和一个ShapeStorage类。 ShapeStorage类有一张地图......
std::map<int, Shape*> shapes;
和一个功能......
Shape * ReturnShapePointer(int key)
{
Shape* shape = shapes[key];
shapes.erase(key);
return shape;
}
我的目标是能够让我的主类实例化一个ShapeStorage对象,在形状图中存储一些Shape *。 然后我想从我的地图中删除它,但不删除值本身。 我希望我的主类仍然能够访问该值。
我试过制作它,我的指针仍然返回正确的值,但我担心因为当我从地图中删除指针时析构函数被调用Shape,所以它只是那时的垃圾数据。
有没有办法解决?
如果您正在存储指针, map
将不会调用您的析构函数。 如果它被调用,它会在其他地方被调用。
尝试运行此示例:
#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;
}
你应该得到这个:
Shape added
Shape removed from map, now exiting
您的地图仅包含指向Shape
的指针。 从地图中删除指针对它指向的对象没有任何影响,它只会破坏地图中的指针。
此外,您的函数将按键执行两次查找。 一次使用operator []
,第二次使用键调用erase ()
时。 这是一个更好的方法:
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;
}
Shape* shape = shapes[key];
shapes.erase(key);
//you can use shape here, without any problem!
这很好。 您可以安全地使用shape
变量。
实际上, delete shape
是您的责任。 它不是std::map
的责任。
std::map
不会自动删除它包含的指针。
所有STL容器都存储值 - 在您的情况下指针。 因此,当您删除条目时,不会调用Shape
的析构函数(不是解构函数:)。
Shape * ReturnShapePointer(int key)
{
Shape* shape = shapes[key];
shapes.erase(key);
return shape;
}
我担心,因为当我从地图中删除指针时,解析器被称为Shape,
上面的代码不会删除Shape
对象。 它只会将其从地图中删除,这似乎正是您想要的。
当您在指针上调用erase时,不会调用析构函数,因此您当前的解决方案应该可以正常工作。
STL具有值语义而不是引用语义。 因此,在插入地图时会生成指针的副本。 副本将消失,但您的原始文件仍将指向它始终执行的相同内存位置,并且该位置中的值仍将存在,直到您通过指针删除它(或直到该值超出范围,如果它是基于堆栈的,并使用&运算符设置指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.