2010-10-19 5 views
1

Essayait de trouver le meilleur moyen d'utiliser ptr_vector pour stocker, accéder et libérer des objets, en particulier lorsque l'objet stocké est hérité d'autres (ptr_vector ne devrait pas avoir de problèmes avec le découpage d'objet). Mais lors de l'exécution du programme ci-dessous, étonnamment la classe dérivée n'est pas détruite. Quelqu'un sait pourquoi?La classe dérivée stockée dans ptr_vector n'est pas détruite

#include <boost/ptr_container/ptr_vector.hpp> 
#include <iostream> 
#include <boost/ptr_container/ptr_map.hpp> 
#include <boost/foreach.hpp> 
using namespace std; 

class A 
{ 
public: 
int id; 
A() {cout<<"Constructed A()"<<endl;} 
A(int i):id(i) {cout<<"Constructed A"<<i<<endl;} 
~A() {cout<<"* Destructed A"<<id<<endl;} 
}; 
class B:public A 
{ 
public: 
int i; 
B() {cout<<"Constructed B"<<endl;} 
B(int ii):i(ii) {id=ii;cout<<"Constructed B"<<i<<endl;} 
~B() {cout<<"* Destructed B"<<i<<endl;} 
}; 

class zoo 
{ 
boost::ptr_vector<A> the_animals; 
public: 
void addAnimal(A* a) {the_animals.push_back(a);} 
void removeAnimal(int id) {the_animals.release(the_animals.begin()+id); } 
void removeOwnership(int id) {the_animals.release(the_animals.begin()+id).release();} 
}; 

int main() 
{ 
zoo z; 
z.addAnimal(new B(0)); 
//delete abc;z.addAnimal(abc);//doing this will cause heap corruption 
B* lion=new B(1); 
z.addAnimal(lion); 
z.removeOwnership(1); 
     delete lion; 
z.removeAnimal(0); 
}//main 

La sortie du programme est:

Constructed A() 
Constructed B0 
Constructed A() 
Constructed B1 
* Destructed B1 
* Destructed A1 
* Destructed A0 

Pourquoi ne pas être DESTRUCTED B0? L'objet a-t-il été coupé?

Répondre

8

Le Destructeur de la classe de base n'est pas virtuelle:

~A() {cout<<"* Destructed A"<<id<<endl;} 

devrait être:

virtual ~A() {cout<<"* Destructed A"<<id<<endl;} 

Pourquoi? Voir When should your destructor be virtual?

+0

Mais je n'utilise pas de fonctions virtuelles du tout. Pourquoi le destructeur devrait-il être virtuel? – Nav

+1

@Nav, voir http://stackoverflow.com/questions/1123044/when-should-your-destructor-be-virtual pour une réponse plus détaillée, mais fondamentalement, si vous supprimez un objet à travers un pointeur à sa base tapez votre base objets destructeur doit être virtuel – Glen

+0

@Glen merci, j'ai inclus le lien dans la réponse. – KeatsPeeks