对C++引用的理解

对C++引用的理解,第1张

对C++引用的理解

文章目录

引用介绍引用和指针常量

引用介绍

引用分为左值引用和在C++11中提出的右值引用,在默认情况下谈及引用均指左值引用。

引用的作用类似于获取变量的地址,是给已声明的变量起别名的一种方法,引用类型引用(refer to)引用另一种类型。引用类型变量的声明格式是将在变量名左边添加&符号,即&D的形式,其中D是引用类型的变量名。

int i = 1;
int &r1 = i;  //r1引用变量i,是i的别名

引用必须初始化,且一个变量引用另一个变量之后,就和该变量绑定在一起,不能再引用背的变量。

引用并非一个对象,而只是已有对象的一个别名。

引用和指针常量

为什么引用必须初始化?一个引用真的只能绑定到一个对象上?引用为变量取一个别名,不是对象,那么它究竟是什么?程序编译后引用变量以什么形式存在?它和普通变量有什么区别?
如果你能清楚回答以上问题,那么下面的内容就不用看了,否则,让我们一起揭开引用的神秘面纱。

	int i = 7;
	int &r = i;

	r = 8;

上面的代码片段在VS2013 环境下反汇编得到的80386汇编代码为

	int i = 7;
00D752C8  mov         dword ptr [i],7  //将文字常量7放入变量i的地址所表示的内存单元中
	int &r = i;
00D752CF  lea         eax,[i]    //将变量i的地址放入寄存器eax中 
00D752D2  mov         dword ptr [r],eax  //将eax中的值,也就是变量i的地址放入变量r的地址所指示的内存单元中

	r = 8;
00D752D5  mov         eax,dword ptr [r]  //将变量r的地址所指示的内存单元中的值,也就是变量i的地址放入寄存器eax
00D752D8  mov         dword ptr [eax],8 //将文字常量8放入寄存eax的值(变量i的地址)所指示的内存单元中

从上述汇编代码可以看出,引用本身也是一个变量,其所代表的内存单元中存放的是引用变量所引用的对象的内存地址。

引用变量和指针常量是等价的吗?

	int j = 6;
	int *const p = &j;

	*p = 9;

上述代码片段对应的汇编代码为

    14: 
    15: 	int j = 6;
003552BE  mov         dword ptr [j],6  
    16: 	int *const p = &j;
003552C5  lea         eax,[j]  
003552C8  mov         dword ptr [p],eax  
    17: 
    18: 	*p = 9;
003552CB  mov         eax,dword ptr [p]  
003552CE  mov         dword ptr [eax],9 

可见引用在内部实现时与指针常量等价。引用和指针常量的区别体现在高级语言层面,指针常量允许寻址,即&i输出的是变量ide地址,但引用变量不允许寻址,&r输出的是变量i的地址而不是变量引用变量r的地址。引用变量r的地址对程序员不可见,由编译器生成。

下面的代码段输出同样的值。

	int i = 7;
	int &r = i;

	r = 8;

	std::cout << &r << std::endl;
	std::cout << &i << std::endl;

引用能用常量指针实现,但是常量指针能实现的功能未必可以用引用实现,如下面的代码片段。

//定义一个元素类型为常量指针的数组
int i =1;
int j = 2;
int *cosnt a[] = {&i, &j}

下面的代码片段无法编译通过。

//不能编译通过,无法定义引用的数组
int i =1;
int j = 2;
int & a[] = {i, j}

综上所述,引用可以视作指针常量,但是两者不完全等同,引用无法实现指针常量的全部功能。

基于上述结论,以下问题便迎刃而解了。

引用不能独立于所引用的对象存在,因为引用变量要求获取引用对象的地址值。

不能返回函数内部非静态局部变量的引用,因为非静态局部变量在函数调用结束后即被销毁,地址不存在。但是可以返回函数内部局部变量,普通的局部变量的生命周期会被编译器自动延长,类对象类型的局部变量会执行拷贝构造函数和析构函数。

不能将一个引用变量绑定多个变量,因为引用变量存储的是引用对象的地址,是一个指针常量,指针值不能改变。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5714519.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存