#include <iostream>
class Class
{
public:
Class() { std::cerr << "ctor" << std::endl; }
~Class() { std::cerr <<"dtor" << std::endl; }
Class(Class&) { std::cerr << "copy ctor" << std::endl; }
Class & operator=(const Class &)
{
std::cerr << "copy operator=" << std::endl;
return *this;
}
Class(Class&&) { std::cerr << "move ctor" << std::endl;}
Class & operator=(Class &&)
{
std::cerr << "move operator="<< std::endl;
return *this;
}
};
int main(int, char**)
{
Class object;
Class && rvr = Class();
object = rvr; // (*)
}
Run Code Online (Sandbox Code Playgroud)
输出是
ctor
ctor
copy operator=
dtor
dtor
Run Code Online (Sandbox Code Playgroud)
1)为什么在行(*)处调用"copy ctor"?
2)如果我每次都必须使用std :: move(),那么"移动语义"和任何移动数据的方法之间有什么区别object.destructive_move();?
3)何时正好调用ctor/operator?
谢谢!
复制ctor不在第(*)行调用,调用复制赋值运算符.我猜这就是你的意思.
由于rvr是左值,因此调用的是复制赋值运算符而不是移动赋值运算符.请注意,表达式的类型与它是否为左值正交.
如果您将赋值语句修改为object = Class();或甚至object = static_cast<Class&&>(rvr),您会发现调用了移动赋值运算符,因为在这两种情况下RHS是一个右值.
这种行为是明智的:比如考虑移动赋值运算符的实现.它的参数有rvalue类型引用,但它仍然是一个左值.如果它是一个rvalue,那么第一次使用该参数可以将其状态修改为"空"对象(移动语义),然后第二次使用该参数可能无法按预期工作.
它实际工作的方式,std::move当你想以一种让它处于"空"状态的方式使用参数时,你会明确地使用它.