我有一个指向对象的指针向量。我需要从向量中删除一个元素,并将该元素放置在另一个列表中。
我了解到可以使用erase来从向量中删除对象,但我也读到它会在执行操作之前调用对象的析构函数。
我需要知道是否擦除对象也会销毁它。
vector::erase
从向量容器中删除并调用其析构函数,但如果包含的对象是指针,则不会拥有销毁它的所有权。
您将需要显式调用delete
来删除每个包含的指针以删除它所指向的内容,例如:
void clearVectorContents( std::vector <YourClass*> & a )
{
for ( int i = 0; i < a.size(); i++ )
{
delete a[i];
}
a.clear();
}
在标准容器中存储原始指针并不是一个好主意。如果您真的需要存储必须由new
分配的资源,则应使用boost::shared_ptr
。请查看Boost文档。
更通用和优雅的解决方案:
此解决方案利用了for_each
和templates
,如@Billy在评论中指出:
// Functor for deleting pointers in vector.
template<class T> class DeleteVector
{
public:
// Overloaded () operator.
// This will be called by for_each() function.
bool operator()(T x) const
{
// Delete pointer.
delete x;
return true;
}
};
这可以被称为:
for_each( myclassVector.begin(),myclassVector.end(),
DeleteVector<myclass*>());
其中,myclassVector
是包含指向 myclass
类对象的指针的向量。
使用示例:
#include "functional"
#include "vector"
#include "algorithm"
#include "iostream"
//Your class
class myclass
{
public:
int i;
myclass():i(10){}
};
// Functor for deleting pointers in vector.
template<class T> class DeleteVector
{
public:
// Overloaded () operator.
// This will be called by for_each() function.
bool operator()(T x) const
{
// Delete pointer.
delete x;
return true;
}
};
int main()
{
// Add 10 objects to the vector.
std::vector<myclass*> myclassVector;
for( int Index = 0; Index < 10; ++Index )
{
myclassVector.push_back( new myclass);
}
for (int i=0; i<myclassVector.size(); i++)
{
std::cout << " " << (myclassVector[i])->i;
}
// Now delete the vector contents in a single line.
for_each( myclassVector.begin(),
myclassVector.end(),
DeleteVector<myclass*>());
//Clear the vector
myclassVector.clear();
std::cout<<"\n"<<myclassVector.size();
return 0;
}
vector<MyObject>
,那么MyObject::~MyObject
将会被调用。vector<MyObject*>
,那么delete <MyObject
instance>
将不会被调用。要在两个向量之间移动MyObject,你需要首先将它插入到目标向量中,然后删除原始向量。请注意,这将创建对象的新副本。当移动指针时,您可以将指针保留在临时变量中,从向量中删除它,然后在需要的位置插入。
这里还有另一种简单的方法来删除并移除向量中的所有项:
template<class T> void purge( std::vector<T> & v ) {
for ( auto item : v ) delete item;
v.clear();
}
是的,erase
会销毁元素。然而,如果您将元素放入另一个容器中,您可能已经复制了它并将其放入该容器中。您可能遇到问题的唯一方式是如果您将指针或类似内容复制到另一个容器中。
vector<Plane *> p, q;
Plane *r = new Plane();
p.push_back(r);
q.push_back(r);
p.erase(p.begin());
r 和 q.begin() 仍然会引用新创建的 Plane 吗? - cesar{ Plane * p = new Plane; }
, 这个行为和之前相同,当p
超出作用域时,它会被“销毁”,但在堆上分配的对象仍然存在。使用裸指针意味着它们是你的责任。 - Kerrek SB当然会。如果对象在向量中不存在,它还可能存在哪里呢?
编辑:这不会删除由指针指向的任何内容。您应该使用管理对象生存期的自动生命周期管理指针,例如 shared_ptr
。
vector::erase
会销毁被移除的对象,这涉及调用其析构函数。