对于以下代码,我对 p3 向量感到困惑,为什么不会为 Test 触发移动运算符?对于 p1 和 p2,我可以理解所有需要复制的元素都结束了。
这是否意味着当我们移动一个向量时,它会修改向量对象,使向量的元素保持不变。而当我们复制一个向量时,我们必须复制每一个元素。是否存在将触发元素的移动运算符的向量操作?
#include <iostream>
#include <vector>
using namespace std;
class Test {
public:
Test(int a) {
std::cout << " default " << std::endl;
}
Test(const Test& o) {
std::cout << " copy ctor " << std::endl;
}
Test& operator=(const Test& o) {
std::cout << " copy assign " << std::endl;
return *this;
}
Test(Test&& o) {
std::cout << " move ctor" << std::endl;
}
Test& operator=(Test&& o) {
std::cout << " move assign " << std::endl;
return *this;
}
};
int main()
{
std::cout << " p: " << std::endl;
std::vector<Test> p = {Test(0), Test(0)};
std::cout << std::endl;
std::cout << " vec p1 " << std::endl;
std::vector<Test> p1 = p;
std::cout << std::endl;
std::cout << " vec p2 " << std::endl;
std::vector<Test> p2;
p2.reserve(2);
p2.emplace_back(0);
p2.emplace_back(0);
std::cout << std::endl;
std::cout << " vec p3 " << std::endl;
std::vector<Test> p3 = std::move(p);
}
输出:
p:
default
default
copy ctor
copy ctor
vec p1
copy ctor
copy ctor
vec p2
default
default
vec p3
回答1
向量本质上是指向数组的指针。移动向量只是在两个向量之间交换数组指针,数组本身是不变的。
回答2
vector
基本上是
template <typename T>
class vector
{
T* data;
T* end_data;
T* end_capacity;
public:
//...
};
当您想要复制它时,您需要为 data
分配新空间以指向然后将元素从源向量复制到目标。
移动时不需要发生这种情况。移动基本上清空了源位置,在这种情况下,这意味着将指针复制到移动到向量中,然后将移动从向量中的指针设置为空。这就是为什么移动可以提高性能的原因。