Something occurred in my program, and I can't find if it's supposed to happen or not. And if it is, I don't see why..
Here's the code :
#include <iostream>
#include <vector>
using namespace std;
class A{
public:
A();
~A();
};
A::A(){
cout << "creating" << endl;
}
A::~A(){
cout << "deleting" << endl;
}
int main(void){
vector<vector<A > > vec;
vec.resize(5);
for(int i = 0; i < 5; ++i){
vec[i].resize(5);
}
cout << "END" << endl;
return 0;
}
And here's the output :
creating
deleting
creating
deleting
creating
deleting
creating
deleting
creating
deleting
END
deleting
deleting
[..more deleting here]
I understand why the destructor is called after the "END" message, but before, I don't. I thought that when the vector resize, the constructor of the class is called, but why the destructor?
In C++03 vector<A>::resize()
has a default parameter, with default value A()
. It's this temporary that's destroyed. The elements of the vectors are copy constructed from it.
This is "fixed" in C++11, where there are two overloads of resize
. One has a single parameter, and value-initializes any additional elements. The other has two parameters, and copy-initializes each additional element from the value supplied. In C++11 this program has this behavior:
creating
creating
creating
<repeated for a total of 25 "creating"s>
creating
creating
creating
END
deleting
deleting
deleting
<repeated for a total of 25 "deleting"s>
deleting
deleting
deleting
In C++03, if an instance of A
is so shockingly expensive to construct that it's worth minimizing the number, then you could shave it from 5 no-args- + 25 copy-constructions down to 1 no-arg- and 25 copy-constructions with something like this:
A default_value;
for (int i = 0; i < 5; ++i) {
// same end result as vec[i].resize(5)
if (vec[i].size() >= 5) {
vec[i].erase(vec.begin() + 5, vec.end());
} else while(vec[i].size() < 5) {
vec[i].push_back(default_value);
}
}
You can probably write it slightly differently, and obviously for your example code you don't need the "if" case. But I don't get many opportunities to say "else while", so I'm taking it.