首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11多移动构造函数调用

C++11多移动构造函数调用
EN

Stack Overflow用户
提问于 2018-02-11 10:37:24
回答 1查看 73关注 0票数 3

这是我用g++ -std=c++11 file.cpp编译的,在研究C++中的move构造器时,我感到非常困惑。

代码语言:javascript
复制
#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"));
}

此程序的输出为:

代码语言:javascript
复制
$ ./a.out 
move
move
move
move
move
move

为什么move构造函数在这里被调用了6次?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-11 10:40:50

因为std::vector::push_back会导致重新分配;当新的size()大于capacity()时,vector会分配新的底层存储,并且所有当前元素都会通过move构造函数移动到新的存储中。在重新分配过程中,元素的移动会导致这些移动构造函数的多次调用。

容量如何增长并没有由标准明确指定;我想这里的每次重新分配都会加倍,那么

代码语言:javascript
复制
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

因此,移动构造函数被调用了6次。顺便说一句,如果你再执行一次push_back,只会调用一次移动构造函数;因为对于第四次push_back,不会发生重新分配。

您可以使用std::vector::reserve来避免重新分配。

代码语言:javascript
复制
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"));
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48727737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档