c++ - C++ 在 std::vector 中移动构造函数多次调用
问题描述
我编写了简单的代码来理解移动语义和移动构造函数。
#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 时,都会执行另一个移动构造函数调用。
附上程序输出
我需要帮助来理解这个奇怪的输出。
谢谢。
解决方案
当向量增长时,它必须重新分配。向量从容量 0 开始,仅在需要时增加容量。通常情况下,容量会增加 10 倍,2
以确保所承诺的时间复杂度push_back
。其他因素也还可以。
您看到的是向量在重新分配时将元素移动到内存中的不同位置。
当您预先分配足够的空间时,您看不到额外的移动:
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();
输出:
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
在这里没有伤害,但不必要的临时对象可能很昂贵,具体取决于如何移动元素的成本很高。
推荐阅读
- angular - 使用 Docker 在 nginx 中部署时,角度未找到资源
- javascript - 通过jquery添加和删除类到自动生成的div?
- javascript - 如何在 Javascript 中检索 Blogger JSON 数据
- apache-spark - 从 Spark UI SQL 选项卡获取查询 DAG 数据的任何 API
- php - PHP ...使用forloop显示数组(调查结果)
- java - 通道注册期间的线程块
- java - Android Studio 在 DefaultHttpClient 中出现错误
- android - 如何在 android firebase 中找到列表的大小?
- spring - 自动连线 getProperty 返回 null
- python - 如何在 numpy.append 中短路展平