J'ai un vecteur de pointeurs vers des objets. J'ai besoin de supprimer un élément du vecteur et de le placer dans une autre liste.
J'ai lu que l'effacement peut être utilisé pour supprimer l'objet du vecteur, mais j'ai également lu qu'il appelle le destructeur d'objets avant de le faire.
J'ai besoin de savoir si l'effacement de l'objet le détruira ou non.
vector::erase
Supprime du conteneur vectoriel et appelle son destructeur, mais si l'objet contenu est un pointeur, il ne s'approprie pas de le détruire.
Vous devrez appeler explicitement delete sur chaque pointeur contenu pour supprimer le contenu vers lequel il pointe, par exemple:
void clearVectorContents( std::vector <YourClass*> & a )
{
for ( int i = 0; i < a.size(); i++ )
{
delete a[i];
}
a.clear();
}
Stocker des pointeurs bruts dans des conteneurs standard n'est pas une bonne idée. Si vous avez vraiment besoin de stocker des ressources qui doivent être allouées par new
, vous devez utiliser boost::shared_ptr
. Consultez la documentation Boost .
Une solution élégante plus générique:
Cette solution utilise for_each
templates
comme l'a souligné @Billy dans les commentaires:
// 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;
}
};
Et cela peut être appelé comme:
for_each( myclassVector.begin(),myclassVector.end(),
DeleteVector<myclass*>());
où, myclassVector
est votre vecteur contenant des pointeurs vers des objets de classe myclass
.
Exemple d'utilisation:
#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>
puis MyObject::~MyObject
sera appelé.vector<MyObject*>
puis delete <MyObject instance>
ne sera pas appelé.Pour déplacer MyObject entre deux vecteurs, vous devez d'abord l'insérer dans le vecteur de destination, puis effacer l'original. Notez que cela créera une nouvelle copie de l'objet. Lorsque vous déplacez des pointeurs, vous pouvez simplement conserver le pointeur dans une variable temporaire, l'effacer du vecteur, puis l'insérer où vous en avez besoin.
Et voici une autre façon simple de supprimer puis de supprimer tous les éléments d'un vecteur:
template<class T> void purge( std::vector<T> & v ) {
for ( auto item : v ) delete item;
v.clear();
}
Oui, bien sûr. Si l'objet n'existe pas dans le vecteur, où d'autre existerait-il?
Edit: Cela pas supprimera tout ce qui est signalé par un pointeur. Vous devez utiliser des pointeurs de gestion automatique à vie, tels que shared_ptr
pour gérer la durée de vie des objets.
Oui, erase
détruit l'élément. Cependant, si vous placez l'élément dans un autre conteneur, vous avez probablement fait une copie en le plaçant dans cet autre conteneur. La seule façon de rencontrer des problèmes est de copier un pointeur ou quelque chose comme ça dans l'autre conteneur.
Oui. vector::erase
détruit l'objet supprimé, ce qui implique d'appeler son destructeur.