首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++移动构造函数多次调用,在std::vector中

C++移动构造函数多次调用,在std::vector中
EN

Stack Overflow用户
提问于 2021-04-27 22:58:52
回答 1查看 94关注 0票数 0

为了理解移动语义和移动构造函数,我编写了简单的代码。

代码语言:javascript
复制
#include <iostream>
#include <vector>

using namespace std;



class Data
{
public:

    Data(int sz)
    {
        cout << "ctor" << endl;
        buffer = new int[sz];
        size = sz;
    }
    Data(Data& other)
    {
        size = other.size;
        cout << "copy ctor" << endl;
        buffer = new int[size];
        memcpy(buffer, other.buffer, size * sizeof(int)); //deep copy
    }
    Data(Data&& r)
    {
        size = r.size;
        cout << "move ctor" << endl;
        buffer = r.buffer;

    }

private:
    double bigValue;
    int* buffer;
    int size;

};



int main(void) 
{

    auto f = []() { cout << "---------------------\n"; };
     

    vector<Data> data;

    data.push_back(  move( Data(1)  ) ); // move constructor called once
    f();

    data.push_back(  move( Data(2)  ) ); // move constructor called twice
    f();

    data.push_back(  move( Data(3)  ) ); // move constructor called 3 times
    f();


    int stop; cin >> stop;

    return 0;
}

我看到了一些奇怪的东西:

每次我调用push_back时,都会执行一次move构造函数调用。

附加的程序输出

我需要帮助理解这个奇怪的输出。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-27 23:05:14

当一个向量增长时,它必须重新分配。向量从容量0开始,只有在需要时才会增加容量。通常,通过2的因子来增加容量以确保push_back所承诺的时间复杂度。其他因素也是可以的。

您所看到的是当重新分配时,向量将元素移动到内存中的不同位置。

当您预先分配足够的空间时,您看不到额外的移动:

代码语言:javascript
复制
vector<Data> data;
data.reserve(5);           // <------------------- reserve
data.push_back(  move( Data(1)  ) );
f();
data.push_back(  move( Data(2)  ) );
f();
data.push_back(  move( Data(3)  ) );
f();

Output

代码语言:javascript
复制
ctor
move ctor
---------------------
ctor
move ctor
---------------------
ctor
move ctor
---------------------

PS:正如评论中提到的,通过std::move进行的转换是多余的。你可以用data.push_back( Data(1) );实现同样的效果,草率地说,因为Data(1)已经是一个临时的,push_back在它可以移动的时候确实会移动。此外(同样来自注释),当您想要在适当的位置构造一个元素时,您应该使用emplace_back,而不是先在向量外创建一个临时元素,然后再将其移入。std::move在这里没有坏处,但不必要的临时操作可能会很昂贵,这取决于移动元素的成本有多高。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67285587

复制
相关文章

相似问题

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