Vector:clear/pop_back won't run destructor

Magicaxis picture Magicaxis · May 22, 2012 · Viewed 7.9k times · Source

I have a vector (pflist) of "Pictureframe"s, and I want to destroy all of them. So I run pflist.clear(); The documentation says that this runs the destructor of each item in the vector, but it isn't!

I have a:

vector<Pictureframe*> pflist;

And here's the rest:

class Pictureframe{
    scene::IMeshSceneNode *picture;
    scene::IMeshSceneNode *frame;

public:
    Pictureframe();
    ~Pictureframe();
};

and then in the cpp file:

Pictureframe::~Pictureframe(){
//  delete picture;
//  delete frame;
    cout<<"Destructor Called.\n\n";
}

There is nary a "Destructor Called" in sight! Here's where I call it:

pflist.clear();

I am sure that this line is being run, and that is populated by 5 pictureframes. I also tried a for loop that went through the vector pop_back'ing, and that had the same problem.

So Destructor, Y U NO CALL?

Answer

Praetorian picture Praetorian · May 22, 2012

Your question doesn't state what the type of the std::vector is. If the type is std::vector<Pictureframe *> then the destructors of each element will not be called when you call std::vector::clear. In this case it is your responsibility to delete these objects before clearing the vector.

If you don't need to dynamically allocate these objects, change the vector type to std::vector<Pictureframe>. Use it as:

std::vector<Pictureframe> vec;
vec.push_back( Pictureframe( ... ) );
// do stuff
vec.clear();

Now the destructor for each object will be called. Remember to create a copy constructor and assignment operator for Pictureframe since it looks like the class is managing some resources.

If you must dynamically allocate Pictureframe objects, change the vector to

std::vector<std::unique_ptr<Pictureframe>> vec;
vec.push_back( std::unique_ptr<Pictureframe>( new Pictureframe( ... ) ) );
// do stuff
vec.clear();

unique_ptr will automatically delete the objects in this case.

Other alternatives are boost::shared_ptr instead of std::unique_ptr or boost::ptr_vector.