有一段时间,这让我感到困惑。到目前为止,我还没有找到满意的答案。问题很简单。何时调用move assignment operator
,何时调用move constructor operator
?
cppreference.com上的代码示例产生以下有趣结果:
a2 = std::move(a1); // move-assignment from xvalue
A a2 = std::move(a1); // move-construct from xvalue
它是如何实现的?如果是这样的话,如果两者都实施了吗?如果它完全相同,为什么有可能创建一个移动赋值运算符重载。
答案 0 :(得分:13)
只有在构造对象时才会执行移动构造函数。移动赋值运算符在先前构造的对象上执行。这与复制案例完全相同。
Foo foo = std::move(bar); // construction, invokes move constructor
foo = std::move(other); // assignment, invokes move assignment operator
如果您没有明确声明它们,编译器会为您生成它们(除了一些例外,其列表太长,无法在此处发布)。
有关隐式生成移动成员函数的完整答案,请参阅this。
答案 1 :(得分:4)
何时调用移动赋值运算符
将 rvalue 分配给对象时,就像在第一个示例中一样。
何时调用移动构造函数?
使用 rvalue 初始化对象时,就像在第二个示例中一样。虽然它不是运营商。
它实现了吗?
不,这决定了它是否可以使用,而不是可以使用它。例如,如果没有移动构造函数,那么构造将使用复制构造函数(如果存在),否则失败(带错误)。
如果是这样的话,如果两者都实施了吗?
赋值赋值运算符,初始化构造函数。
为什么有可能创建一个移动赋值运算符重载,无论如何它都是相同的。
不完全相同。它是在已经存在的对象上调用的;调用构造函数以初始化以前不存在的对象。他们经常要做不同的事情。例如,赋值可能必须删除在初始化期间不存在的内容。
答案 2 :(得分:2)
这与正常的复制分配和复制构造相同。
A a2 = std::move(a1);
A a2 = a1;
那些调用move / copy构造函数,因为a2
尚不存在且需要构造。分配没有意义。此表单称为复制初始化。
a2 = std::move(a1);
a2 = a1;
那些调用移动/复制赋值运算符,因为a2
已经存在,所以构造它没有意义。
答案 3 :(得分:0)
在以下期间调用移动构造函数:
在以下期间调用移动分配操作:
以下示例代码说明了这一点:
#include <iostream>
#include <utility>
#include <vector>
#include <string>
using namespace std;
class A {
public :
A() { cout << "constructor called" << endl;}
~A() { cout << "destructor called" << endl;}
A(A&&) {cout << "move constructor called"<< endl; return;}
A& operator=(A&&) {cout << "move assignment operator called"<< endl; return *this;}
};
A fun() {
A a; // 5. constructor called
return a; // 6. move assignment operator called
// 7. destructor called on this local a
}
void foo(A){
return;
}
int main()
{
A a; // 1. constructor called
A b; // 2. constructor called
A c{std::move(b)}; // 3. move constructor called
c = std::move(a); // 4. move assignment operator called
a = fun();
foo(std::move(c)); // 8. move constructor called
}
输出:
constructor called
constructor called
move constructor called
move assignment operator called
constructor called
move assignment operator called
destructor called
move constructor called
destructor called
destructor called
destructor called
destructor called