2010-08-19 3 views
3

Supposons que j'ai deux conteneurs, contenant des pointeurs sur des objets, qui partagent certains de leurs éléments. de http://www.cplusplus.com/reference/stl/list/erase/ il est dit que:Conteneurs STL, supprimez un objet de deux conteneurs

Cela réduit efficacement la taille de la liste par le nombre d'éléments supprimés, appelant la destructor de chaque élément avant.

Comment puis-je supprimer un objet de deux conteneurs sans appeler le destructor deux fois:

exemple

#include <map> 
#include <string> 
using namespace std; 
//to lazy to write a class 
struct myObj{ 
      string pkid; 
      string data; 
}; 
map<string,*myObj> container1; 
map<string,*myObj> container2; 

int main() 
{ 
     myObj * object = new myObj(); 
     object->pkid="12345"; 
     object->data="someData"; 
     container1.insert(object->pkid,object); 
     container2.insert(object->pkid,object); 

     //removing object from container1 
     container1.erase(object->pkid); 
     //object descructor been called and container2 now hold invalid pointer 

     //this will call try to deallocate an deallocated memory 
     container2.erase(object->pkid); 

} 

s'il vous plaît conseiller

+4

En fait, le destructeur d'objet n'est pas appelé du tout; 'effacer 'supprime simplement le pointeur de la carte. Si la carte contient des objets plutôt que des pointeurs, alors ils appellent leurs destructeurs. –

Répondre

4

Si vos conteneurs tiennent des pointeurs, le destructor pour ces objets ne seront pas appelés (la STL ne suit pas les pointeurs et appeler la destructor du pointée). Inversement, si vos conteneurs contenaient eux-mêmes les objets en taille réelle, le destructeur de ces objets serait appelé.

Vous avez également rencontré des erreurs de syntaxe dans votre déclaration de carte et dans les instructions d'insertion. Essayez d'exécuter le code suivant. Notez que le destructeur est seulement appelé une fois (pour l'instruction delete). Le destructeur n'est jamais appelé pour les instructions d'effacement.

#include <map> 
#include <string> 
#include <iostream> 
using namespace std; 
//to lazy to write a class 
struct myObj{ 
    ~myObj() { 
     cout << "DESTRUCTION" << endl; 
    } 
      string pkid; 
      string data; 
}; 
map<string,myObj*> container1; 
map<string,myObj*> container2; 

int main() 
{ 
     myObj * object = new myObj(); 
     object->pkid="12345"; 
     object->data="someData"; 
     container1.insert(pair<string,myObj*>(object->pkid,object)); 
     container2.insert(pair<string,myObj*>(object->pkid,object)); 

     //removing POINTER from container1 
     container1.erase(object->pkid); 
     //object's destructor has NOT been called yet 

     //removing POINTER from container2 
     container2.erase(object->pkid); 
     //object's destructor STILL hasn't been called 

     delete object; // DESTRUCTION! 
} 
+1

Je vois. donc dans le cas de pointeurs, je dois les supprimer explicitement après les avoir retirés de tous les conteneurs. merci! – Alex