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?
No. You never need to explicitly call a destructor (except with placement new ). A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects.
vector::resize() The function alters the container's content in actual by inserting or deleting the elements from it. It happens so, If the given value of n is less than the size at present then extra elements are demolished.
One way of deleting a vector is to use the destructor of the vector. In this case, all the elements are deleted, but the name of the vector is not deleted.
The destructor is being called three times, for a , lol and b . In your case, a and b are instantiated using the default constructor .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With