左值和右值 左值引用和右值引用----C++学习(2)

左值和右值

在理解左值引用和右值引用之前需要先理解C++中对于左值和右值的定义,两者之间的区别为对应的值是否有具体的名称

左值

对于程序中的在内存中的有具体的实体并且有具体名称的变量或对象被称为左值
例如:
Student s1;
Student s2=s1;
s1有实体有名称,为左值
s2有实体有名称,为左值

右值

对于程序中在内存中无实体,无名称或有实体,无名称的值被称为右值
例如:
1、
int a=0;
int b=a+2;
a和b有实体有名称为左值
在运行过程中0和(a+2)应该在数据寄存器中,且无名称 为右值
2、
Student s1=new Student();
Student* s2=new Student();
s1和s2有实体有名称为左值 指针内存中的实体保存的为地址
new Student(); 返回一片区域的首地址,地址值在寄存器中,没有名称 为右值

左值引用和右值引用

左值引用和右值引用的作用都是为了不再创建新的对象,而是取一个别名,继续使用引用的对象,不同的是引用的对象为左值还是右值

左值引用

例:
Student s1(“xiaohong”,28);
Student &s2=s1;
s2.name=“xiaoming”;
s1为左值,左值引用
此时s2实际上是s1的别名,两者操作同一块内存
s1的name也被更新为"xiaoming"

右值引用

例:
1、
Student s1(“xiaohong”,28);
Student &&s2=s1;
s2.name=“xiaoming”;
s1为左值,因此该操作为左值引用
此时s2实际上是s1的别名,两者操作同一块内存
s1的name也被更新为"xiaoming"

2、
Student &&s2=getStudent();
getStudent()为右值,因此该操作为右值引用
此时s2实际上是getStudent()返回对象的别名,这样将不需要重新构造对象,再执行=赋值操作,直接增加了运行效率
getStudent()返回的对象实际上保存在栈上,但是这样依赖,在返回结束后,该对象不会被释放,生命周期被拉长,随着s2的结束而结束

3、
int a=1;
int &&b=a; 左值引用
int &&c=a+1; 右值引用

引用折叠

组合: 引用有两种:左值引用和右值引用。所以有四种引用组合:左值-左值(& &)、左值-右值(& &&)、右值-左值(&& &)、右值-右值(&& &&)。意思为:左值引用的左值引用、左值引用的右值引用、右值引用的左值引用、右值引用的右值引用。前面的引用符号可以看作一种型别,后面的引用符号看作该型别的引用。
规则: 如果任一引用为左值引用,则结果为左值引用。否则(即两个皆为右值引用),结果为右值引用。
引用的引用允许出现的四种语境: 模版实例化、auto型别生成、创建和运用typedef和别名声明、以及decltype。

其他疑点

如题,正常情况下引用代表变量的一个别名,如:
int a = 1;
int &b = a; //ok(b是a的一个别名,两者指向相同的内存地址)
int &c = 2;//error(不能将非常量左值引用绑定到右值2)
const int &d = 3;//ok(为什么常量左值引用却可以绑定到右值3?)
允许引用绑定非左值的初衷在于“让传值还是传引用成为函数本身的细节,调用者不用去关心”,这一点,在const引用上可以达到,而非const引用,调用者无法不关心传值还是传引用,所以干脆在C++ 2.0禁止掉了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月光在发光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值