标签:fun 清空 形式 标准库 错误 不能 重点 amp strong
结论:
int i = 10;
i = i + 1; //i是个左值,不是右值,虽然它出现等号右边
//i用在等号右边的时候,i有一种右值属性;不是右值;
//i用在等号左边的时候,用的是i代表的内存中的地址,i有一种左值属性;
//一个左值,他可能给同时具有左值属性和右值属性
赋值运算符
int a;
cout << a = 4 << endl;
(a = 4) = 8; //整个赋值语句的结果是左值;
取地址 &
int a = 5; //变量a是个左值
&a; //
容器中的下标/迭代器
string str = "hello world!";
str[0];
vector<int>::iterator iter;
iter++;
iter--;
通过判断一个运算符在一个字面值上能不能操作,可以判断运算符是否用到的是左值;
左值引用(绑定到左值)
int value = 10;
int &ref_val = value;
ref_val = 13; // value = 13;
const引用(常量引用),也是左值引用,不希望改变值的对象;
int value = 10;
const int &ref_val = value;
//ref_val = 18; 不可修改
右值引用,绑定到右值:是个引用,主要用于临时对象;
int &&ref_right_value = 3; //绑定到一个值上
ref_right_value = 5;
将变量绑定到左值上;
int a = 1;
int &b{a}; //b绑定到a
//int &c; 错误,引用必须要初始化
//int &c = 1; 错误,左值引用必须绑定到左值,不能绑定到右值
const int &c = 1; //const引用可以绑定到右值
//相当于系统产生一个临时变量,将c绑定到临时变量中;
引用右值,也就是说,绑定到右值;必须是绑定到右值的引用;通过&&
&&右值引用,用来绑定一些即将销毁的或者是一些临时对象上;
右值引用也是引用,可以把右值引用理解成一个对象的名字;
int &&ref_right_value = 3;
ref_right_value = 5;
能绑定到左值引用上的,一般都不能绑定到右值;
右值引用也绑定不到左值上;
string str_te{"Hello world"};
string &ref_str_1{str_te}; //可以,左值引用绑定到左值;
//string &ref_str_2{"Hello world"}; 不可以,左值引用不能绑定到临时变量; 临时变量被系统当做右值
const string *const_ref_str{"hello world"}; //可以,创建一个临时对象,绑定到左值上,const不仅可以绑定到右值,还可以执行到string的隐式类型转换并将所得到的的值放到string临时变量中
//string &&ref_right_1{str_te}; //右值引用不能绑定到一个左值;
string &&ref_right_2{"hello world"}; //可以,绑定到一个临时变量,临时变量的内容“hello world”
int i = 10;
int &ri_1 = i; //正确,左值引用
int &&ri_2 = i; //错误,不能将右值引用绑定到左值上;
int &&ri_3 = i * 100; //正确,右值引用绑定到右值
int &r4 = i * 100; //左值引用不能绑定到右值
const int &r5 = i * 100; //const引用可以绑定到右值;
总结
前置++和后置++的区别
前置++
++i; //左值表达式,++i直接给变量i+1,然后返回i本身
//因为i是变量,所以可以被赋值;
int i = 100;
(++i) = 199; //i = 199;
int &r1 = ++i; //成功绑定左值 r3就是i的别名;
后置++
i++; //右值表达式,i++先产生一个临时变量,记录i的值用于使用的目的,i的值被使用之后,再给i+1,接着返回这个临时变量
//(i++) = 199; //错误 右值无法赋值;
int i = 1;
int &&ref = i++; //成功绑定右值; 此后ref的值和i没有关系
// int &r2 = i++; //左值引用不能绑定到右值表达式上
重点
ref虽然是右值引用(绑定到了右值),但是ref本身是左值(要把ref看成是一个变量);因为它在等号左边;并且左值引用可以绑定到ref这个左值上;
所有变量看成左值,因为他们有地址,用右值引用无法绑定;
任何函数中的形参都是左值;
void func(int &&v); //w是右值引用,但w本身是左值;
临时对象都是右值;
int i = 10;
int &&ref = std::move(i);
i = 20; //i的值改变,ref的值也变量; ref代表i;
int &&ri = 100; //ri是左值
int &&re = std::move(ri);
//string的移动构造函数做了哪些事情
// 1. 将str清空; 2. 给def分配内存 3.将str的内容移动到def
string str = "hello world";
const char* q = str.c_str(); //q是str实际所占内存
string def = std::move(str); //=会调用string的移动构造函数,导致str中的内容移动到def中
const char* p = def.c_str(); //p是def实际所占内存
string str = "hello world";
std::move(str); //单独执行 str内容没空,只是将str转成右值;
string str = "hello world";
string &&def_r = std::move(str); //def_r右值引用 绑定到str上;
//建议:使用了std::move之后,不要用str了;
标签:fun 清空 形式 标准库 错误 不能 重点 amp strong
原文地址:https://www.cnblogs.com/Trevo/p/13343862.html