- 左值和右值
- 用到左值的运算符有哪些?
- 引用分类
- 分类
- 右值引用的目的
- std::move函数
int i = 10;//对象:一块内存区域 i =20;
左值:能在赋值语句等号左侧的东西,它代表了一个地址
右值:不能作为左值的值就是右值,右值不能出现在赋值语句中等号的左侧
结论:
c++一条表达式,要么是右值,要么就是左值。左值有时候当作右值使用。
例如:
int i = 0; i = i + 1;//i是左值 虽然出现在右边 //i出现在右边 我们说i有右值属性 //一个左值既有左值属性也有右值属性用到左值的运算符有哪些?
- 赋值表达式
int a = 10;
- 取地址 &
&a;
- string,vector下标[]都需要左值。迭代器。
string abc = "I Love China!"; vector::iterator iter; iter++; iter--; abc[0];
- 其他一些运算符判断是否左值
//i++; //5++; //左值表达式就是左值,右值表达式说的就是右值 //左值:代表一个地址,结果是一个对象就是地址 //求值结果为对象的表达式,不代表一定是左值,具体再分析引用分类 分类
细分为:左值引用、右值引用和const引用
//1.左值引用 int value = 10; int &refval = value; refval = 13;// value = 13; //int &ref;错误必须初始化 引用必须初始化 //int &ref = 1;不能绑定到右值 //2.const引用 常量引用 不能改变值的对象,可以绑定左右值 const int &refval2 = value; const int &refval22 = 10; //实际是通过临时变量 绑定到临时变量 //refval2 = 100;错误不能修改 //3.右值引用(绑定到右值)用&&来体现 用于存放一些即将销毁的临时变量 int &&refvalue3 = 3; refvalue3 = 5;
能绑定到左值上的不能绑定到右值上,反之同理。
string st = "I Love China!"; string &st1 = st;//可以 string &st2 = "I Love China!";//不可以,左值引用不能绑定到临时变量,临时变量被系统当作右值 const string &st3 = "I Love China!";//可以 string &&st4 = st;//不行 int i = 2; int &r1 = i int &&r2 = i * 100;//不可以 i*100是一个右值了
总结:
- 返回左值引用的函数,连同赋值,下标和前置递增递减运算符都是返回左值表示式的例子,可以用左值引用
- 返回非引用类型的函数,连同算术,关系,位和侯值递增递减运算符都是右值例子,可以用右值引用
- 但是可以用const引用使用上面的表达式
- 虽然int &&r2中r2是右值引用 ,但是r2本身是左值
- 临时变量都是右值
++i;//左值表达式,返回是i本身地址 先加后用 i++;//右值表达式,先产生临时变量 +1之后再返回临时变量。先用后加右值引用的目的
- c++11引入 &&代表一种新的数据类型
- 提高程序运行效率,把拷贝对象变成了移动对象来处理提高了运行效率
- 移动的对象如何发生。&&应付移动构造函数和移动赋值运算符
移动 实际上没有做移动操作。只是把一个左值强制转换为右值。
建议执行之后就不要使用第一个变量了。
int tt = 100; // int &&ttt = tt;//错误 int &&tttt = std::move(tt); tttt = 10;//tt也为10了; string st = "I Love China!"; string df = std::move(st);//st为空了,因为string 里的移动构造函数把st的内容移动到了df 而不是std::move的影响 这里的df是新的对象 string &&df1 = std::move(st);//建议这样执行之后就不要使用st了 df1 = "f22f"; string &&df2 = std::move(st);//这里df2和st是同一个意思,st不为空,不会发生string移动构造函数;



