vector.clear() - destructor not called?
Christopher Bludau

Hiho,

I have a class containing the following:

typedef std::vector<CBasicButton*> button_vector_type;

class CButtonMenu
{
private:
  button_vector_type button_list;
...
}

and in the destrutor I have:

CButtonMenu::~CButtonMenu(void)
{
  this->button_list.clear();
}

I have a breakpoint in the destrutor of CBasicButton but it is NOT called...
In the reference I read this:

vector::clear public member function
void clear ( );

Clear content

All the elements of the vector are dropped: their destructors are called, and then they are removed from the vector container, leaving the container with a size of 0.

What did I miss? ???

Matthew Leverton

Clearing a vector doesn't free the (pointer) objects inside them, nor does it call their destructors.

SiegeLord

The elements you are storing are pointers. Pointers have no destructors, they are just addresses to memory elsewhere.

Thomas Fjellstrom

Could probably use one of the <algorithm> or whatever functions to do something like: foreach(vec, delete);

Schyfis

I figured that out the hard way too.
I would call each element's destructor first and then clear the vector.

Christopher Bludau

Ok, so the reference and destructor part is only true when the vector contains objects and not pointers. Makes sense.

Which means I have to delete the stuff myself. Just thought that I don't have to when I read the reference.

Thanks!

Schyfis said:

I would call each element's constructor

constructor?

Schyfis

Typo, destructor.

bamccaig

A little smart pointer magic can make it automated.

#include <boost/shared_ptr.hpp>
#include <vector>

typedef boost::shared_ptr<CBasicButton> button_ptr_type;
typedef std::vector<button_ptr_type> button_vector_type;

You shouldn't need to call this->button_list.clear() in your destructor because your button_vector_type property is static. When the CButtonMenu instance is destroyed, the vector and all of its contents will automatically be cleaned up because they're stack allocated. The only concern is whether or not the vector contains dynamically allocated memory, which would need to be deallocated first (which again is where smart pointers come in).

Working example:

main.hpp#SelectExpand
1#ifndef MAIN_HPP 2 #define MAIN_HPP 3 4 #include <boost/shared_ptr.hpp> 5 #include <iostream> 6 #include <vector> 7 8class Example; 9typedef boost::shared_ptr<Example> Example_ptr; 10typedef std::vector<Example_ptr> Example_ptr_vec; 11 12class Example 13{ 14public: 15 int x; 16 17 Example(int); 18 ~Example(void); 19 20 void Print(void) const; 21}; 22 23int main(int, char *[]); 24void test(void); 25 26#endif

main.cpp#SelectExpand
1#include "main.hpp" 2 3int main(int argc, char *argv[]) 4{ 5 std::cout << "Before..." << std::endl; 6 test(); 7 std::cout << "...After." << std::endl; 8 9 return 0; 10} 11 12void test(void) 13{ 14 Example_ptr x; 15 Example_ptr_vec v; 16 17 x.reset(new Example(5)); 18 v.push_back(x); 19 20 v[0]->Print(); 21} 22 23Example::Example(int x): 24 x(x) 25{ 26} 27 28Example::~Example(void) 29{ 30 std::cout << "Example destroyed." << std::endl; 31} 32 33void Example::Print(void) const 34{ 35 std::cout << "Example{x:" << this->x << "}" << std::endl; 36}

[bamccaig@rufus smartptr]$ g++ main.cpp -o smartptr
[bamccaig@rufus smartptr]$ ./smartptr
Before...
Example{x:5}
Example destroyed.
...After.

Thread #599750. Printed from Allegro.cc