左值引用和右值引用

左值和右值

1.在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。左值绝大多数时候在等号左边,右值在右边,但这并不总是对的。

例如:int i=10 ;变量i是一个在内存中有位置的实际变量,数字10没有存储空间,没有位置,所以我们就不能写成int 10=i,因为10没有位置,我们不能在10中存储数据。但是,我们可以让另一个变量int a=i;这样一个左值就等于了另一个左值。

2.一个对象被当作左值时,使用的是它的地址,被用作右值时,使用的是它的内容(值)。

左值引用

1.左值引用通常称为“引用”,引用是为对象起的别名,必须被初始化,和变量绑定在一起,且将一直绑定在一起。

可以通过&获取左值引用

type &引用名=左值表达式

可以把引用绑定在左值上,而不能绑定在要求转换的表达式、字面常量或是返回右值的表达式。

例如:

int i=10;
int &j=i;          //正确
int &j=i*2;        //错误,i*2是一个右值 
const int &j=i*2;  //正确,可以将一个const引用绑定在右值上 

右值引用

1.右值引用就是必须绑定到右值上的引用

我们通过&&获取右值引用

type &&引用名=右值表达式

右值引用有一个重要的性质——只能绑定到将要销毁的对象上。

例如:

int &&j=i;    //错误,i是一个左值
int &&j=i*2;  //正确,i*2是一个右值 

2.右值不仅只是字面量,也可以是函数结果。

#include<iostream>
 
int GetValue() {
	return 10;
}
 
int main() {
	int i=GetValue(); //正确 
	GetValue()=5;     //编译错误,因为GetValue()是一个右值 
}

要解决上面的编译错误情况,就要用到左值引用,让函数的返回值为左值。

#include<iostream>
 
int& GetValue() {  //左值引用,函数返回值为左值
	static int value=10;
	return value;
}
 
int main() {
	int i=GetValue(); //正确 
	GetValue()=5;     //正确
}

扩展

1.如果一个函数,它有一个值,我们可以用左值或右值来调用它。

#include<iostream>
 
void SetValue(int value) {
	
} 
 
int main() {
	int i=10;
	SetValue(i);
	SetValue(10);    //临时值 
}

2. 注意,下面为错误代码:

#include<iostream>
 
void SetValue(int& value) {
	
} 
 
int main() {
	int i=10;
	SetValue(i);
	SetValue(10);    //错误,不能用左值来引用右值 
}

 要解决上述情况,我们可以改用const引用(与右值兼容),const引用既可以接收左值,也能接收右值。

void SetValue(const int& value) {
	
} 
 
int main() {
	int i=10;
	SetValue(i);     //正确 
	SetValue(10);    //正确 
}

3.右值引用只能传递右值。

void PrintName(std::string&& name) {
	std::cout<<name<<std::endl
} 
 
int main() {
	std::string firstname="wang";
	std::string lastname="wenhao";
	
	std::string fullname=firstname+lastname;
	
	PrintName(fullname);       //错误 ,右值引用不能传递左值 
	PrintName(firstname+lastname);
}

4.特殊情况:下面代码中的第一个重载函数为const引用,既可以接收左值,又可以接收右值,但由于存在第二个重载函数为右值引用,所以当传入参数为右值时,会优先调用第二个重载函数。

运行结果为:  [lvalue]:wangwenhao
                     [rvalue]:wangwenhao

#include<iostream>
void PrintName(const std::string& name) {
	std::cout<<"[lvalue]:"<<name<<std::endl; 
} 
 
void PrintName(std::string&& name) {
	std::cout<<"[rvalue]:"<<name<<std::endl;
} 
 
 
int main() {
	std::string firstname="wang";
	std::string lastname="wenhao";
	
	std::string fullname=firstname+lastname;
	
	PrintName(fullname);       
	PrintName(firstname+lastname);
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值