右值变量只有内容,没有承载这个内容的实体,他表示一个数据信息,你不能像修改左值那样去修改右值变量,不能去取右值变量的地址(但是右值实际上是不是也像左值变量那样也存储在栈地址中我还不清楚)
右值引用是右值变量的别名,左值引用是左值变量的别名。可以把左值想象为容器(不是stl那个容器),而右值是容器里的内容。
std::move操作是获取一个基本内置类型的右值引用,对一个左值使用move操作后会破坏这个左值!所以要注意move之后这个左值就不能再使用它原来的值了(cpp primer P471)!(但是可以给它赋新值)
移动构造函数依赖move操作。
对左值变量而言,它是存在实体的,对一个基本内置类型左值变量A使用move函数(或者调用他的移动运算符/移动构造函数)来初始化另一个同类变量B,相当与把A的内容剪切到B上,
注意B并不是接管了A的内存地址(从下面的结果看出2者并不在同一地址),而是“窃取”了A的内容,省去了复制构造的操作,比复制构造有更高的效率(以破坏源对象为代价)。
对于我们自定义的类型,在使用一个对象A去构造另一个对象B,而又不再需要原对象A的场景里(因为移动构造会破坏掉源对象),我们可以自定义这个类的移动构造函数,移动操作并没有规定必须是把一个地址的内容移动到另一个地址,
我们自定义的移动构造可以是接管源对象的地址来达到“移动”的目的(或者对类内每个内置类型成员都调用std::move操作)
#include <iostream> using namespace std; int main(){ string str1("hello"); cout<<"addr str1: "<<&str1<<endl; string str2 = move(str1); cout<<"str2: "<<str2<<" addr str2: "<<&str2<<endl; cout<<"addr str1 after: "<<&str1<<endl; cout<<"str1: "<<str1<<endl; return 0; } /* result: addr str1: 0x7fffffffda10 str2: hello addr str2: 0x7fffffffda30 addr str1 after: 0x7fffffffda10 str1: */
标签:变量,右值,move,左值,构造,移动 From: https://www.cnblogs.com/tan-wm/p/17437299.html