C++中为什么引用可以作为函数返回值?

C++中为什么引用可以作为函数返回值?

本文背景

程序设计与算法(三)第01周测验003:好怪异的返回值里面,题目的解答是这样子的:

#include <iostream>

using namespace std;
int & getElement(int * a, int i)
{
	return a[i];
}

int main()
{
	int a[] = {1,2,3};
	getElement(a,1) = 10;
	cout << a[1] ;
	return 0;
}

有读者奇怪的是,为什么int & getElement(int * a, int i)要加&,直接int getElement(int * a, int i)不可以么?

真机测试

那我们在CLion里不加&试试。

#include <iostream>

using namespace std;
int getElement(int * a, int i)//不加&
{
	return a[i];
}

int main()
{
	int a[] = {1,2,3};
	getElement(a,1) = 10;
	cout << a[1] ;
	return 0;
}

调试信息

调试,返回错误:

====================[ Build | test1 | Debug ]===================================
/opt/clion/bin/cmake/linux/bin/cmake --build /home/mrcangye/CLionProjects/test1/cmake-build-debug --target test1 -- -j 2
[ 50%] Building CXX object CMakeFiles/test1.dir/main.cpp.o
/home/mrcangye/CLionProjects/test1/main.cpp: In function ‘int main()’:
/home/mrcangye/CLionProjects/test1/main.cpp:12:20: error: lvalue required as left operand of assignment
   12 |  getElement(a,1) = 10;
      |                    ^~
make[3]: *** [CMakeFiles/test1.dir/build.make:63: CMakeFiles/test1.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:76: CMakeFiles/test1.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/test1.dir/rule] Error 2
make: *** [Makefile:118: test1] Error 2

调试信息指出了程序第12行,getElement(a,1) = 10;出现错误。

这也是接下来需要讲述的问题。

参考资料

为了解决这个问题,我拿出了C++ Primer Plus 第六版中文版 人民邮电出版社2012年七月第一版,2019年1月北京第31次印刷版本,第8章 函数探幽 第268页

基本原理

重点在于:

getElement(a,1) = 10;

这是一个赋值语句

在赋值语句中,语句左边,也就是=号左边,必须是可以修改的值,深入了解一下,必须是一个可以修改的内存块。重点是这个等号左边的值必须是可以修改的。

常规(非引用)的返回类型是放在=右边的,是不能通过地址访问的值。不可以出现在=号左边。

为什么呢?因为常规的返回值是存在临时内存单元中的,运行到下一条语句时,这个返回值就不存在了。return后面的表达式将结果的值计算出来,然后这个值被复制到一个临时位置,返回给调用函数,调用函数再到临时位置使用这个值

复制到
返回给
return返回值
临时位置
调用函数调用

解答

上面的原理和调试出错的信息是一致的。

如果我们不加&,那么返回的是一个确切的int数值11 = 10是不符合左边可以修改的值的要求。

为了符合这个要求,我们就需要加&号,使得这个函数getElement(a,1)返回值是int &

,并将int &返回,就是:a[1] = 10,这样就合法了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章