Seo*_*oul 3 c++ vector stdvector c++11
我编写了这个,g++ -std=c++11 file.cpp我很困惑通过研究移动构造函数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"));
}
Run Code Online (Sandbox Code Playgroud)
该程序的输出是:
$ ./a.out
move
move
move
move
move
move
Run Code Online (Sandbox Code Playgroud)
为什么移动构造函数在这里调用了6次?
因为std::vector::push_back重新分配原因; 当new size()大于capacity() vector分配新的底层存储时,所有当前元素都通过移动构造函数移动到新存储.在重新分配期间移动元素会导致移动构造函数的这些多次调用.
标准没有明确规定容量增长的方式; 我想这里每次重新分配都会加倍
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
Run Code Online (Sandbox Code Playgroud)
因此移动构造函数被调用了6次.顺便说一句,如果再执行push_back一次,将只调用一次移动构造函数; 因为第4次push_back没有重新分配.
您可以使用std::vector::reserve以避免重新分配.
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"));
Run Code Online (Sandbox Code Playgroud)