This question already has answers here:
How to enforce move semantics when a vector grows?
(3个答案)
去年关闭。
首先,我不会英语,所以我使用翻译。
该代码是支持 vector 中移动语义的代码。
创建单个 vector 并将Test对象插入push_back()方法的代码。
该代码的结果是,每次由于push_back()方法而添加Test对象时,都应该调用move构造函数,对吗?
但是,仅当插入新对象时,编译器才调用move构造函数,而旧对象则调用copy构造函数。
为什么会这样呢?我想念什么吗?
(3个答案)
去年关闭。
首先,我不会英语,所以我使用翻译。
该代码是支持 vector 中移动语义的代码。
创建单个 vector 并将Test对象插入push_back()方法的代码。
该代码的结果是,每次由于push_back()方法而添加Test对象时,都应该调用move构造函数,对吗?
但是,仅当插入新对象时,编译器才调用move构造函数,而旧对象则调用copy构造函数。
为什么会这样呢?我想念什么吗?
#include <iostream>
#include <vector>
using namespace std;
class Test
{
public:
Test(int data1, int data2) :data1(data1), data2(data2)
{
cout << "Normal Constructor" << endl;
}
Test(const Test& src)
{
cout << "Copy Constructor" << endl;
this->data1 = src.data1;
this->data2 = src.data2;
}
Test(Test&& rhs)
{
cout << "Move Constructor" << endl;
this->data1 = rhs.data1;
this->data2 = rhs.data2;
rhs.data1 = 0;
rhs.data2 = 0;
}
Test& operator=(const Test& src)
{
if (this == &src)
return *this;
cout << "Copy assignment operator" << endl;
this->data1 = src.data1;
this->data2 = src.data2;
return *this;
}
Test& operator=(Test&& rhs)
{
if (this == &rhs)
return *this;
cout << "Move assignment operator" << endl;
this->data1 = rhs.data1;
this->data2 = rhs.data2;
rhs.data1 = 0;
rhs.data2 = 0;
return *this;
}
private:
int data1, data2;
};
int main()
{
vector<Test> vec;
for (int i = 0; i < 5; i++)
{
cout << "Iteration " << i << endl;
vec.push_back(Test(100, 100));
cout << endl;
}
}
最佳答案
std::vector
选择复制构造函数而不是move构造函数的原因是您的move构造函数不是nothrow
。为什么std::vector
在乎?
好吧,std::vector
具有一些异常安全保证。例如,参见 std::vector::push_back
的异常保证:
这意味着,当以某种方式引发异常时,它不会炸毁整个容器,在这种情况下,强异常保证甚至可以保证错误的插入对vector完全没有影响。
拥有一个非noexcept
move构造函数是一个问题,因为如果会引发重新分配,则std::vector
无法回到有效状态,因为它可能已经将其一半的项移到了另一半上,然后尝试将它们移回旧的内存位置也可能会抛出异常。复制不会出现此问题,因为旧项目保持完好无损,因此,如果有副本抛出,std::vector
只需要破坏到目前为止已复制的所有(新)项目并放弃。您作为集合的用户,可以保证插入或重新分配不当都会使所有其他项目保持完整。这就是为什么noexcept
保证只有在保证移动不会抛出的情况下才使用move-constructor的原因。
关于c++ - 支持 vector 中的移动语义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55153410/