C++ 11:当调用move ctor/operator =时?

use*_*506 3 c++ c++11

#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?

谢谢!

ndk*_*pel 7

复制ctor不在第(*)行调用,调用复制赋值运算符.我猜这就是你的意思.

由于rvr是左值,因此调用的是复制赋值运算符而不是移动赋值运算符.请注意,表达式的类型与它是否为左值正交.

如果您将赋值语句修改为object = Class();或甚至object = static_cast<Class&&>(rvr),您会发现调用了移动赋值运算符,因为在这两种情况下RHS是一个右值.

这种行为是明智的:比如考虑移动赋值运算符的实现.它的参数有rvalue类型引用,但它仍然是一个左值.如果它是一个rvalue,那么第一次使用该参数可以将其状态修改为"空"对象(移动语义),然后第二次使用该参数可能无法按预期工作.

它实际工作的方式,std::move当你想以一种让它处于"空"状态的方式使用参数时,你会明确地使用它.