C++的左值引用和初识右值引用

引用(左值引用)

#include <iostream>
#include <typeinfo>
/*
C++的引用 引用的和指针的区别?
1.左值引用和右值引用
2.引用的实例

引用是一种更安全的指针
1.引用是必须初始化的,指针可以不初始化
2.引用只有一级引用,没有多级引用;指针可以有一级指针,也可以有多级指针
3.定义一个引用变量,和定义一个指针变量,其汇编指令是一模一样的;通过引用变量修改所引用内存的值
  和通过指针解引用修改指针指向的内存的值,其底层指令也是一模一样的.例如如下为两者的汇编代码   
	int* p = &a;
00007FF6BE1D6A25  lea         rax,[a]
00007FF6BE1D6A29  mov         qword ptr [p],rax
	int& b = a;
00007FF6BE1D6A2D  lea         rax,[a]
00007FF6BE1D6A31  mov         qword ptr [b],rax
*/

void swap(int &x, int &y)
{
	int temp = x;
	x = y;
	y= temp;
}

void swap2(int* x, int* y)
{
	int temp = *x;
	*x = *y;
	*y = temp;
}

int main()
{
	int a = 10;
	int* p = &a;	
	int& b = a;

	*p = 20;
	std::cout << "a:" << a << " *p:" << *p << " b:" << b << std::endl;

	b = 30;
	std::cout << "a:" << a << " *p:" << *p << " b:" << b << std::endl;

	/*
	编译错误: error C2440 : “初始化”: 无法从“int”转换为“int &”
	*/
	//int& c = 20;

	int c = 100;
	int d = 200;
	swap(c, d);//通过引用实现两数交换
	//swap2(&c, &d);//通过指针实现两数交换
	std::cout << "c:" << c << " d:" << d << std::endl;

	int array[5] = {};
	int *p2= array;
	//定义一个引用变量,来引用array数组
	int(&p3)[5]= array;
	std::cout <<"sizeof(array):" <<sizeof(array) << std::endl;
	std::cout <<"sizeof(p2):"<< sizeof(p2) << std::endl;
	std::cout <<"sizeof(p3):"<< sizeof(p3) << std::endl;

}

输出如下:

a:20 *p:20 b:20
a:30 *p:30 b:30
c:200 d:100
sizeof(array):20
sizeof(p2):8
sizeof(p3):20

右值引用

#include <iostream>
#include <typeinfo>
/*
右值引用
1.int &&c=20;专门用来引用右值类型,指令上,可以自动产生临时量,
  然后直接引用临时量 c=40;
2.右值引用变量本身是一个左值,只能用左值引用来引用它
3.不能用一个右值引用变量,来引用一个左值
*/
int main()
{
	int a = 10;//左值,它有内存,有名字,值可以修改的
	int& b = a;

	//C++11提供了右值引用
	int&& c = 20;//20是右值:没有内存,没有名字
	//c = 30;c是可以被修改的

	int& e = c;//一个右值引用变量,本身是一个左值
	//int&& f = c;//编译将报错,因为c是一个右值引用变量(本身是一个左值),不用右值引用变量f来引用一个左值的。
	/*
	这种写法右值引用也是可以。相当于下面的做法
	int temp=20;
	temp->d
    汇编指令如下:
		int&& c = 20;//20是右值:没有内存,没有名字
		00007FF65BC61EDD  mov         dword ptr [rbp+64h],14h
		00007FF65BC61EE4  lea         rax,[rbp+64h]
		00007FF65BC61EE8  mov         qword ptr [c],rax

		const int& d = 20;
		00007FF65BC61EEC  mov         dword ptr [rbp+0A4h],14h
		00007FF65BC61EF6  lea         rax,[rbp+0A4h]
		00007FF65BC61EFD  mov         qword ptr [d],rax
	*/
	const int& d = 20;
	//d = 30;//编译报错,d是不能被修改

	
}
posted @ 2025-10-19 20:43  焦涛  阅读(2)  评论(0)    收藏  举报