[英]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.