web-dev-qa-db-fra.com

Est-ce que vector :: erase () sur un vecteur de pointeurs d'objets détruit l'objet lui-même?

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.

39
cesar

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_eachtemplates 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;
}
59
Alok Save
  • Si tu as un vector<MyObject> puis MyObject::~MyObject sera appelé.
  • Si tu as un 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();
}
9
Tomas Andrle

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.

2
Puppy

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.

2
Billy ONeal

Oui. vector::erase détruit l'objet supprimé, ce qui implique d'appeler son destructeur.

2
Dominic Gurto