I've compiled this with g++ -std=c++11 file.cpp and I am quite confused by studying the move constructor in C++.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class P {
public:
string* ptr_;
P(string name) { ptr_ = new string(name); }
~P() { delete ptr_; }
P(P&& pother) : ptr_(move(pother.ptr_)) {
cout<<"move"<<endl;
pother.ptr_=nullptr;
}
void print() {cout << *ptr_ << endl;}
};
int main()
{
vector<P> ppl;
ppl.push_back(P("Jojo"));
ppl.push_back(P("Jojo"));
ppl.push_back(P("Jojo"));
}
The output of this program is:
$ ./a.out
move
move
move
move
move
move
Why is the move constructor called 6 times here?
Because std::vector::push_back causes reallocation; when the new size() is greater than capacity() vector allocates new underlying storage and all the current elements are moved to new storage via move constructor. The moving of elements during reallocation cause these multiple invocations of move constructor.
How capacity grows is not explicitly specified by standard; I suppose it's doubled for every reallocation here, then
ppl.push_back(P("Jojo")); // 0 element(s) moved, 1 element added, 1 move(s) in all; size=1, capacity=1
ppl.push_back(P("Jojo")); // 1 element(s) moved, 1 element added, 2 move(s) in all; size=2, capacity=2
ppl.push_back(P("Jojo")); // 2 element(s) moved, 1 element added, 3 move(s) in all; size=3, capacity=4
// assume the 4th push_back is performed
ppl.push_back(P("Jojo")); // 0 element(s) moved, 1 element added, 1 move(s) in all; size=4, capacity=4
So the move constructor is invoked 6 times. BTW if you perform push_back one more time, only one time move constructor will be invoked; because for the 4th push_back no reallocation happens.
You can use std::vector::reserve to avoid reallocation.
vector<P> ppl;
ppl.reserve(3); // prohibit reallocations for the following 3 push_back
ppl.push_back(P("Jojo"));
ppl.push_back(P("Jojo"));
ppl.push_back(P("Jojo"));
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