左值、右值,左值引用、右值引用、move

027左值和右值问题

#include<iostream>
#include<cstdlib>
#include<string>
#include <vector>

using namespace std;


int main(void)
{
	int number01 = 10;	//每个对象占有一块内存空间

	number01 = 22;
	//左值当右值使用,
	number01 = number01 + 1;//number01本质上是左值。虽然它出现在等号右侧。
	/*
	//number01用在等号右侧的时候,我们说number01具有右值属性,不是右值。
	*number01出现在左边,用的是内存中的地址,nubmer01具有左值属性
	*用在右侧,用的是nubmer01的值。
	*总结:一个左值,可以同时具有左值属性和右值属性。
	 */
	//1.赋值运算符结果是左值
	printf("%d", number01 = 4);
	//整个赋值语句的结果是个左值,可以赋值
	(number01 = 4) = 23;

	//2取地址
	&number01;
	cout << &number01 << endl;

	//string vector []都是左值
	string str = "jisuanji";
	str[1];
	//迭代器也是左值
	vector<int>::iterator iter;
	iter++;
	
	system("pause");
	return 0;
}

/*
*(1)左值:能在赋值语句等号左侧的东西,它能够代表一段内存空间
*	右值:不能作为左值的值就是右值,右值不能出现在赋值语句中等号的左侧。
*	结论:c++中的一条表达式,要么是左值,要么是右值,不可能两者都不是。、
*	但是有时候左值也可以当做右值使用。
*
*用到左值的运算符:
*	1.=赋值运算符 左侧是左值、
*	2.&取地址运算符
*	3.cstring vector 下标[]都是左值
*	4.迭代器的递增,递减运算符等
*	一般在字面值上不能操作,就需要用到左值。
*	在资料上叫左值表达式就是左值,,右值表达式就是右值
*	左值:代表一个地址,所以左值表达式求值结果,就是一个对象,就需要有地址。变量名为内存空间的别名。
*		求值结果为对象的表达式,不一定是左值,需要具体分析。
*
*(2)
*
*(3)
*
*
*/

028左值_右值_左值引用_右值引用

#include<iostream>
#include<cstdlib>
#include<string>
#include<vector>

using namespace std;


int main(void)
{
	//左值引用
	int number01 = 10;
	int&reference_number01 = number01;
	reference_number01 = 20;

	//2const 引用
	const int reference_number02 = number01;

	//右值引用-绑定到右值  临时
	int&& reference_number03 = 3;//使用完3之后不需要保留
	reference_number03 = 12;


	//左值引用   指针可以指向一个空,可以不初始化,但是引用必须初始化
	//没有空引用,左值引用初始化的时候就绑定到左值
	int number04 = 200;
	int&Reference_number05 = number04;
	//int &number06 = 4;//error 左值引用不能绑定到右值,必须绑定到左值
	const int &tem = 3;//const引用可以绑定到右值。const引用比较特殊。系统内部生成了一个临时变量
	/*
	 * temValue=3;
	 * int&tem=temValue;
	 */

	//右值引用--必须是绑定到右值的引用。使用&&、--绑定临时对象上
	int &&reference_number07 = 3;	//右值引用可以理解成一个对象的名字。



	//其他范例
	string str{ "jisuanjizuchengyaunli" };
	string &reference_str = str;
	//string &reference_str02{ "jisuanizuchengyaunli" };//error不可以,左值引用不能绑定到临时对象
	//临时变量被系统当做右值
	//
	const string &reference_str03 = "jisuanjizuchengyuanli";//ok
	//const不但可以绑定到右值,而且可以执行隐式类型转换,经临时对象绑定到string临时变量中。
	
	//string &&reference_str04{ str };//error,右值引用不能半丁到左值
	string &&reference_str05{ "jisuanjizjiifisidf" };//可以绑定到临时对象

	int number06 = 100;
	int&reference_number08 = number06;
	//int&&reference_number09 = number06;//error

	//右值结果绑定到右值
	int &&reference_nubmer10 = number06 * 100;//ok

	//为什么前置运算符是一个左值表达式??
	/*++i;
	 *系统直接在内部给变量i加1,然后返回i本身
	 * 因为i是变量,所以可以被赋值,赋值后还是一个对象
	 *
	 * i++为什么是一个右值表达式???
	 * 先用后加,
	 * 先产生一个临时变量,记录的值用于使用,再给i加1,接着返回这个临时变量(临时变量是右值)
	 */

	int number11 = 300;
	(++number11) = 199;//number11=199
	//(number11++) = 2000;//error
	int&&reference13 = number11++;//成功绑定右值,但是reference11绑定的不是number11,绑定的是返回的临时量

	//std::move()函数--左值转换为右值
	int number14 = 14;
	int&&reference_number15 = std::move(number14);//ok
	reference_number15 = 15;
	cout << reference_number15 << endl;	//15,可以绑定

	int &&reference_nubmer16 = 100;
	int&&reference_number17 = std::move(reference_nubmer16);	//ok 将一个左值引用转化为右值


	string str18 = "jisuanjizuchegnaun";//没有移动,触发了string类的移动构造函数。移动后把str18清空了。reference19是重新开辟的内存。
	//string reference19 = std::move(str18);
	
	//把一段右值绑定到右值上
	string &&str20 = std::move(str18);
	
	system("pause");
	return 0;
}

/*
*(1)引用分类
*	1.左值引用-绑定到左值
*	2.常量引用-不改变原来的值
*	3.右值引用  使用&& c++11标准
*(2)左值引用是什么?
*	引用左右,绑定到左值上
*
*(3)右值引用,必须绑定到右值上
*为什么引入右值引用?
*	希望右值引用来绑定一些即将销毁的或者一些临时对象上。
*总结:能绑定到左值上的对象一般不能绑定到右值上。
*	返回左值引用的函数连同赋值,下标,解引用,和前置递增递减运算符都是返回表达式的例子。
*	我们可以将一个左值引用绑定到这列表达式的结果上。
*
*	返回非引用类型的函数,连同算术,关系,以及后置递增递减运算符(i--),不能将一个左值引用绑定到这类
*	表达式上,但是可以将一个const或者右值引用绑定到这列表达式上。
*
*1.所有的变量,看成左值,因为他们是由地址的
*2.任何函数的形参都是左值。如void function(int&a);a虽然是引用,但是是左值
*3.临时对象是右值。
*
*
*(4)右值引入目的
*	1.右值引入是c++11的新概念,可以认为&&是一种新的数据类型,引入这种新的数据类型目的见2.
*	2.引入&&是为了提高运算效率,把拷贝对象变成移动对象来提高运送效率。拷贝时候需要分配内存,
*		然后再一个一个项拷贝,移动直接把内存块指针转给B,而不需要分配内存。具体见移动构造函数章节。
*	3.移动对象是如何发生的?怎么触发移动对象?
*		当用一个对象给另一个对象赋值,移动移动构造函数,移动赋值运算符(需要的参数是右值引用)
*		拷贝构造函数,赋值运算符需要的参数是左值引用
*
*(5)std::move()函数
*	std::move()只有一个目的:把一个左值,强制转换为一个右值。--结果:一个右值可以绑定上去了。
*
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值