今天遇到了这个问题,浅浅记录一下
问题描述
问题分析:
首先分析一下这句话:非常量引用的初始值必须为左值
可以得到两个关键词 非常量引用 和 左值
“非常量引用”这个不用多说,形如int& a
可以是一个非常量引用。
有这么一段代码
int tmp;
int test01(int i)
{
tmp = i + 10;
return tmp;
}
int& test02(int i)
{
tmp = i + 10;
return tmp;
}
int main()
{
int a = test01(10);
cout << a << endl;//20
int b = test02(10);
cout << b << endl;//20
}
在test02中引用作为函数的返回值
类型 &函数名(形参列表){ 函数体 }
1.引用作为函数的返回值时,必须在定义函数时在将&写在函数名之前
2.用引用作函数的返回值的最大的好处是在内存中不产生返回值的副本
特别注意:返回值时返回一个局部变量是非法的,因为在函数执行完后函数就被销毁了,此时再返回的参数将是一个不确定的值。
那么对于变量c和变量d
int& c = test01(10);
int& d = test02(10);
变量d调用函数test02,就相当于test02不会产生临时变量,而是直接把temp本身返回给main函数,又由于temp是全局变量,所以在程序结束前temp始终保持有效,故这种做法是安全的。
(图片来源:伯乐在线)
变量c调用函数test01就会报出:非常量引用的初始值必须为左值
的错误
左值
最常见的误区就是:赋值号左边的就是左值,右边的就是右值<—但这个左右并不是绝对的。
形如
int a = 10;//a是左值 10是右值
int c = a;//a是左值 c是左值
string s1 = “Hello World”;//s1是左值 Hello World是右值
这里的左值,可以理解为在内存中有具体的地址的变量,而不是一个短暂的临时变量。
简单点说就是看能不能对一个表达式取地址 ?左值 :右值
在test02中,返回值是一个引用,也就是返回了全局变量temp本身,是一个左值;而在test01中,返回全局变量temp的值时,C++会在内存中创建临时变量并将temp的值拷贝给该临时变量。当返回到主函数main后,会把临时变量的值来初始化变量c,由于临时变量的生命周期短暂,无法通过地址找到对应的变量,结果自然会报错
解决办法
可以通过创建一个变量,将函数的返回值赋给这个变量,然后再用该变量来初始化引用:
int C = test01(10);
int& c = C;
注意,通过关键字const也可以实现功能
const int& c = test01(10);
相当于
int temp = test01(10);
const int &a = temp;
这就是C++中const特殊的地方
总结
1、搞懂左值和右值的概念
2、不能返回局部变量的引用
3、C++中产生的临时对象是不可修改的,即默认为const的
4、非常量引用的初始值必须是左值 即一个非const的左值的引用是不能和右值绑定在一起的,而一个const的左值引用则是可以的
文章为自我回顾和分享,如有错误之处敬请指正。