【C/C++】【类和对象】左值(引用)和右值(引用)
2021-04-12 18:28
标签:fun 清空 形式 标准库 错误 不能 重点 amp strong 结论: 赋值运算符 取地址 & 容器中的下标/迭代器 通过判断一个运算符在一个字面值上能不能操作,可以判断运算符是否用到的是左值; 左值引用(绑定到左值) const引用(常量引用),也是左值引用,不希望改变值的对象; 右值引用,绑定到右值:是个引用,主要用于临时对象; 将变量绑定到左值上; 引用右值,也就是说,绑定到右值;必须是绑定到右值的引用;通过&& &&右值引用,用来绑定一些即将销毁的或者是一些临时对象上; 右值引用也是引用,可以把右值引用理解成一个对象的名字; 能绑定到左值引用上的,一般都不能绑定到右值; 右值引用也绑定不到左值上; 总结 前置++和后置++的区别 前置++ 后置++ 重点 ref虽然是右值引用(绑定到了右值),但是ref本身是左值(要把ref看成是一个变量);因为它在等号左边;并且左值引用可以绑定到ref这个左值上; 所有变量看成左值,因为他们有地址,用右值引用无法绑定; 任何函数中的形参都是左值; 临时对象都是右值; 【C/C++】【类和对象】左值(引用)和右值(引用) 标签:fun 清空 形式 标准库 错误 不能 重点 amp strong 原文地址:https://www.cnblogs.com/Trevo/p/13343862.html左值和右值
int i = 10;
i = i + 1; //i是个左值,不是右值,虽然它出现等号右边
//i用在等号右边的时候,i有一种右值属性;不是右值;
//i用在等号左边的时候,用的是i代表的内存中的地址,i有一种左值属性;
//一个左值,他可能给同时具有左值属性和右值属性
用到左值的运算符有哪些:
int a;
cout
int a = 5; //变量a是个左值
&a; //
string str = "hello world!";
str[0];
vector
左值表达式、右值表达式
总结:
引用分类
三种形式的引用
int value = 10;
int &ref_val = value;
ref_val = 13; // value = 13;
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++; //左值引用不能绑定到右值表达式上
void func(int &&v); //w是右值引用,但w本身是左值;
右值引用的引入目的
std::move函数
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了;
下一篇:C语言基础
文章标题:【C/C++】【类和对象】左值(引用)和右值(引用)
文章链接:http://soscw.com/index.php/essay/74837.html