我试图在用户想要删除对象时删除向量中的对象指针。我试图:
我在DataBase类中有一个字符串到向量的映射。并且向量包含指向对象的指针。像这样:
“database.h”中objectMap
和objectector
的定义
private:
typedef std::vector<Object *> objectVector;
typedef std::map<std::string, objectVector> objectMap;
objectMap objects;
在“database.cpp”中实施deleteId
bool DataBase::deleteId(int id)
{
// vectors
for(objectMap::iterator vec = objects.begin(); vec != objects.end(); ++vec)
{
objectVector v = vec->second;
// objects
for(objectVector::iterator obj = v.begin(); obj != v.end(); ++obj)
{
if((*obj)->getId() == id)
{
delete *obj; // pointer
*obj = 0;
v.erase(obj); // erase from vector
modified = true;
return true;
}
}
}
return false;
}
我目前正在尝试调试程序,我打印出整个对象地图,看看删除是否有效。问题是删除后对象指针仍然存在,即使函数确认删除(即返回true)。有人可以解释一下发生了什么吗?
答案 0 :(得分:2)
objectVector v = vec->second;
此按值复制矢量,因此您指的是副本,而不是真正的矢量。
建议将该行改为
objectVector& v = vec->second; // Reference to the "real" vector
使对象迭代器失效没有问题,因为一旦遇到删除元素,你就会退出该函数。
答案 1 :(得分:1)
您的代码错误至少是因为您没有删除原始向量中的元素。使用对向量的引用
for(objectMap::iterator vec = objects.begin(); vec != objects.end(); ++vec)
{
objectVector &v = vec->second;
另外考虑一种方法,如果在向量中删除一个元素之后,向量变为空,那么也许你还应该删除映射中的相应元素。
例如)没有测试)
bool DataBase::deleteId(int id)
{
bool modified = false;
for ( auto it1 = objects.begin(); !modified && it1 != objects.end(); ++it1 )
{
auto it2 = std::find_if( it1->second.begin(), it1->second.end(),
[&]( Object *o ) { return ( o->getId() == id ); } );
modified = it2 != it1->second.end();
if ( modified )
{
delete *it2;
it1->second.erase( it2 );
if ( it1->second.empty() ) it1 = objects.erase( it1 );
}
}
return modified;
}