如何理解引用做函数返回值时,函数调用可以作为左值

前言

最近在进行C++的学习,初次接触到C++中引用的概念。在学习到引用做函数返回值时,其中有一点:其函数调用可以作为左值。虽然这个知识点不难理解,但也让我疑惑,为什么在之前对函数学习中,并没有接触到函数调用的这个做法。由于引用在实际程序运行时,执行的并不是表面上的代码,它会自动被修改,这就影响到我们对它进一步的理解。

后来结合C++中对引用声明的处理,以及一些简单的代码语句,理解到其本身可能并不复杂。下面让我们来一起看一看。

引用的声明以及简单的代码

我们知道,引用的本质在C++内部实现是一个指针常量,即: 

int& tmp = a;   //a为已定义的一个变量
tmp = 10;

本质上会在C++内部被替换成:

int* const tmp = &a;
*tmp = 10;

理解了以上内容后,我们就可以进入正题了,下面分别声明了两种函数的返回类型,一种是引用,另一种是常见的整型。

int func1 ()   //整型
{
    static int a = 10;
    return a;
}

int& func2 ()   //引用
{
    static int b = 10;
    return b;
}

int main()
{
    func1() = 5;  //1  error
    func2() = 5;  //2
    
    return 0;

}

很明显可以知道,func1作为左值的写法是错误的,函数func1的返回值是a,但是单单只是返回a的值,也就是10,即对一个常数进行了赋值操作。

fun2函数内,定义了一个整型变量b,并将它返回,返回类型为Int& 。 这里可以理解成,返回时系统对整型变量b进行了一次int& b = b;的操作,或者说是 int& ? = b; 即你并不知道它的别名,不过这都不影响。而根据上面所提到的内部替换,其作为左值可以理解成这样一个过程:

func2()=5  =>  b=5 =>  *b = 5 

这里的变量b,不代表整数10的原因就是:本质上它其实是一个指针,而且这个指针在使用的时候,会自动的进行解引用的操作。所以它能实际修改静态变量b的值。

基于上面的说明,我们的指针返回类型,其实也能作为左值。

int* func(int* a)
{
    *a = 2;
	return a;
}

int main()
{
	int b = 1;
	*(func(&b)) = 10;
    cout << b << endl;
	system("pause");
	return 0;
}

上述代码中,函数func的返回类型为int*,其实就是变量b的地址。对它进行解引用操作后,就可以作为左值赋值,其输出结果也确实为10。 

结语

关于左值和右值的问题,网上其实有很多更专业的文章可以阅读。在这里所展示出来的,更多的是个人不太严谨的理解。主要目的是记录一下学习的过程,以及如果能对看到这里的同样的小萌新有帮助,那就太好了。

同时,在这方面,如果有其他想要弄清楚问题,也欢迎各位一起交流!

你可能感兴趣的:(c++)