C++ 当移动到非右值引用时会发生什么?

C++ 当移动到非右值引用时会发生什么?,c++,c++11,C++,C++11,所以我已经被这件事折磨过好几次了。这两者之间的区别是什么: Movable&& object = std::move(another_movable); 这是: Movable object = std::move(another_movable); 看起来两者应该是一样的,但在第二个例子中,我总是会得到令人费解的行为(对象的属性发生变化)。为什么会这样 Movable&& object = std::move(another_movable); 这使另

所以我已经被这件事折磨过好几次了。这两者之间的区别是什么:

 Movable&& object = std::move(another_movable);
这是:

 Movable object = std::move(another_movable);
看起来两者应该是一样的,但在第二个例子中,我总是会得到令人费解的行为(对象的属性发生变化)。为什么会这样

Movable&& object = std::move(another_movable);
这使另一个引用与另一个对象相同

Movable object = std::move(another_movable);

这使得一个新对象从一个右值
初始化为另一个可移动的

可能将其与左值引用版本进行比较会有所帮助:

Movable object = std::move(another_movable);
Object& object = another_object;

Object object  = another_object;
第一个是对左值的引用,因此不调用构造函数。它只是引用名为
的对象,另一个\u对象
,就像指针一样<代码>对象对象创建一个全新的对象,以便调用构造函数(不假设复制省略)


现在右值引用是相同的,但它们是专门为右值定制的。它们现在引用从中初始化的右值

如前所述,首先是复制引用。与所有指针类型一样,除非返回类型在堆上,否则不应该将其作为右值

然而,第二个要比只是一个右值初始化复杂一些。考虑:

Moveable object = another_moveable;

后者似乎是从真正的、非强制转换的右值初始化的。但是看到了吗

前者实际上取决于构造函数Moveable有什么

至于意外行为,可以说,这很可能是因为遗传丢失。i、 e.如果另一个_moveable仅从moveable派生,moveable将仅对另一个_moveable的可移动父对象使用右值初始化,并且派生对象拥有的任何数据现在都将丢失


只是强调一下:具有右值初始化的Moveable并不意味着另一个对象只是获得一个新引用,右值初始化是为了让堆上存储的数据保持原样,只从旧对象复制新对象中的指针和引用。rvalue初始化仍然会复制整个对象,但之后它会确保当旧对象被销毁时,其堆上的数据将保留下来,这应该通过更改旧对象的指针来完成!编译器实际上并没有执行任何操作,程序和使用的头文件必须确保完成预期的操作

一个创建一个引用,另一个实例化一个对象。所以第一个调用移动构造函数,第二个调用移动赋值?如果你对第二个例子有问题,你是在做一些非常错误的事情。从头开始学习移动语义。(对于上面的问题,没有真正的建议,因为它没有包含足够的信息)第二个使用move构造函数,如果有(否则它使用copy构造函数,如果有)。第一个只是创建一个引用。未创建新对象。@juanchopanza:或复制构造函数,如果无法访问移动构造函数