上一讲链接:
引用的使用场景:
在日常的使用过程中,一般我们使用引用的场景分为两种情况,分别是引用作为函数的参数和引用作为函数的返回值。接下来会一 一进行分析。
先上完整代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//1.引用作为函数参数
void func(int& a, int& b)
{
int sum = a + b;
cout << "sum=" << sum << endl;
}
void test01()
{
int a = 10;
int b = 20;
func(a, b);
}
//2.引用作为函数的返回值
int& func2()
{
int b = 10;//不要返回局部变量的引用
int& p = b;
return p;
}
int& func3()
{
static int b = 10;
return b;
}
void test02()
{
int& q = func2();
q = 100;
cout << q << endl;
func2() = 200;
cout << q << endl;
cout << "func2=" << func2() << endl;
func3() = 100;
cout << "func3()=" << func3() << endl;
}
int main()
{
test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
引用作为函数的参数:
一般我们在设计函数时,往往会带有该函数的入口参数,类似于C语言中的指针操作,只不过在C++中换成了引用。接下来具体代码分析:
void func(int& a, int& b)
{
int sum = a + b;
cout << "sum=" << sum << endl;
}
void test01()
{
int a = 10;
int b = 20;
func(a, b);
}
我们还是按照老样子对代码逐一进行分析:
上述代码相对来说比较简单,首先我们定义了两个整型变量a
和b
,然后设计了一个求和函数,传入func
函数的入口参数为a
和b
。
func
的入口参数分别是引用a
和引用b
,分别对传入该函数的入口参数的内存空间进行取别名操作,进而分别对该内存空间取值,并且进行求和,最终打印求和值sum
返回。最终结果如下图:
int& func2()
{
int b = 10;//不要返回局部变量的引用
int& p = b;
return p;
}
void test02()
{
int& q = func2();
q = 100;
cout << q << endl;
func2() = 200;
cout << q << endl;
cout << "func2=" << func2() << endl;
}
我们还是按照老样子对代码逐一进行分析:
如上所示,我们创建了一个函数func2
,进入该函数,首先创建了一个整型变量b
,并且取值为10
。并且引用对b所在的内存空间取别名为p
,并且最终返回该p
。退出func2
函数后,将引用p
传递给引用q
,并且通过q
将内存空间b
修改为100
,最终进行打印。最终结果如下图所示:
看似是没有问题的,我们继续分析:
如果直接将200赋值给func2,然后依次打印p和func2()返回的值,结果会怎样呢?
我们通过上图会发现,正常情况下func2的返回值应该是200才对,可是为什么是10呢?其实我们上面编写的代码是错误的,只是编译器没有检测出来而已,因为func2中的变量b是局部变量,退出func2函数时,该局部变量所在的内存空间其实是已经不存在了,已经被销毁了。所以虽然上述结果看似是正确的,只不过是通过引用q来对func2所在的内存空间进行修改罢了。
那么我们如果要返回的是局部变量,并且要进行引用时,我们应该将局部变量置于堆区或者静态区,具体操作如下:
int& func3()
{
static int b = 10;
return b;
}
void test02()
{
func3() = 100;//如果要函数当左值,那么该函数必须返回引用
cout << "func3()=" << func3() << endl;
}
唯一和之前的代码有区别的在于我们将局部变量置于静态区,最终结果如下图:
结束语
如果觉得这篇文章还不错的话,记得点赞 ,支持下!!!