I wrote this code to examine behaviour of destructors in c++
#include <vector>
#include <iostream>
using namespace std;
class WrongDestructor
{
private:
int number;
public:
WrongDestructor(int number_) :
number(number_)
{}
~WrongDestructor() {
cout<<"Destructor of " <<number<<endl;
// throw int();
}
};
int main(int argc, char *argv[])
{
std::vector<WrongDestructor> wrongs;
for(int i = 0; i < 10; ++i) {
wrongs.push_back(WrongDestructor(i));
}
return 0;
}
What I found interesting is the output of my program:
Destructor of 0
Destructor of 0
Destructor of 1
Destructor of 0
Destructor of 1
Destructor of 2
Destructor of 3
Destructor of 0
Destructor of 1
Destructor of 2
Destructor of 3
Destructor of 4
Destructor of 5
Destructor of 6
Destructor of 7
Destructor of 0
Destructor of 1
Destructor of 2
Destructor of 3
Destructor of 4
Destructor of 5
Destructor of 6
Destructor of 7
Destructor of 8
Destructor of 9
Destructor of 0
Destructor of 1
Destructor of 2
Destructor of 3
Destructor of 4
Destructor of 5
Destructor of 6
Destructor of 7
Destructor of 8
Destructor of 9
It means that much more objects are created than I thought. I expected to have obviously 10 in the collection and maybe next ten created as temporary objects when I fill the collection in the for loop. But there are more of them, some of them are even created more often then the other ones.
When
vectormust allocate a larger memory block to hold elements, the new elements are move-constructed into the new, larger memory block. Because your type defines no move constructor or copy constructor, you get the compiler provided default copy constructor instead. The default copy constructor does a simple memberwise copy of all members in the class.Additionally, inserting the element itself using
push_backrequires moving or copying it in to thevector. As a result, you will get copies there too, assuming your compiler doesn’t optimize this out. (Note that you can avoid these copies by usingemplace_back.)As a result, you are getting several copies of instances inserted into the container early, because when e.g.
1is copied into a larger memory buffer inside ofvector, it is destroyed in the old, smaller, buffer.You can see this behavior more clearly by defining a copy and/or move constructor:
This program gives the following output: http://ideone.com/S5Zf41